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

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

Issue 2965603002: Update hover states when dragging the mouse into an element (Closed)
Patch Set: hover drag Created 3 years, 5 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 6453 matching lines...) Expand 10 before | Expand all | Expand 10 after
6464 6464
6465 while (inner_element_in_document && 6465 while (inner_element_in_document &&
6466 inner_element_in_document->GetDocument() != this) { 6466 inner_element_in_document->GetDocument() != this) {
6467 inner_element_in_document->GetDocument().UpdateHoverActiveState( 6467 inner_element_in_document->GetDocument().UpdateHoverActiveState(
6468 request, inner_element_in_document); 6468 request, inner_element_in_document);
6469 inner_element_in_document = 6469 inner_element_in_document =
6470 inner_element_in_document->GetDocument().LocalOwner(); 6470 inner_element_in_document->GetDocument().LocalOwner();
6471 } 6471 }
6472 6472
6473 UpdateDistribution(); 6473 UpdateDistribution();
6474 Element* old_active_element = ActiveHoverElement(); 6474 Element* old_active_element = ActiveHoverElement();
mustaq 2017/07/10 15:40:45 This is not your change but this looks odd: all us
lanwei 2017/07/12 21:03:10 Done.
6475 if (old_active_element && !request.Active()) { 6475 if (old_active_element && !request.Active()) {
6476 // The oldActiveElement layoutObject is null, dropped on :active by setting 6476 // The oldActiveElement layoutObject is null, dropped on :active by setting
6477 // display: none, for instance. We still need to clear the ActiveChain as 6477 // display: none, for instance. We still need to clear the ActiveChain as
6478 // the mouse is released. 6478 // the mouse is released.
6479 for (Element* element = old_active_element; element; 6479 for (Element* element = old_active_element; element;
6480 element = FlatTreeTraversal::ParentElement(*element)) { 6480 element = FlatTreeTraversal::ParentElement(*element)) {
6481 element->SetActive(false); 6481 element->SetActive(false);
6482 user_action_elements_.SetInActiveChain(element, false); 6482 user_action_elements_.SetInActiveChain(element, false);
6483 } 6483 }
6484 SetActiveHoverElement(nullptr); 6484 SetActiveHoverElement(nullptr);
6485 } else { 6485 } else {
6486 Element* new_active_element = inner_element_in_document; 6486 Element* new_active_element = inner_element_in_document;
6487 if (!old_active_element && new_active_element && 6487 if (!old_active_element && new_active_element &&
6488 !new_active_element->IsDisabledFormControl() && request.Active() && 6488 !new_active_element->IsDisabledFormControl() && request.Active() &&
6489 !request.TouchMove()) { 6489 !request.TouchMove()) {
6490 // We are setting the :active chain and freezing it. If future moves 6490 // We are setting the :active chain and freezing it. If future moves
6491 // happen, they will need to reference this chain. 6491 // happen, they will need to reference this chain.
6492 for (Element* element = new_active_element; element; 6492 for (Element* element = new_active_element; element;
6493 element = FlatTreeTraversal::ParentElement(*element)) { 6493 element = FlatTreeTraversal::ParentElement(*element)) {
6494 user_action_elements_.SetInActiveChain(element, true); 6494 user_action_elements_.SetInActiveChain(element, true);
6495 } 6495 }
6496 SetActiveHoverElement(new_active_element); 6496 SetActiveHoverElement(new_active_element);
6497 } 6497 }
6498 } 6498 }
6499 6499
mustaq 2017/07/10 15:40:45 The |if-else| blocks above covers two changes in a
6500 // Do not set hover state if event is from touch and on mobile. 6500 // Do not set hover state if event is from touch and on mobile.
6501 bool allow_hover_changes = 6501 bool allow_hover_changes =
6502 !(request.TouchEvent() && GetPage() && 6502 !(request.TouchEvent() && GetPage() &&
6503 GetPage()->GetVisualViewport().ShouldDisableDesktopWorkarounds()); 6503 GetPage()->GetVisualViewport().ShouldDisableDesktopWorkarounds());
6504 6504
6505 // If the mouse has just been pressed, set :active on the chain. Those (and 6505 // If the mouse has just been pressed, set :active on the chain. Those (and
6506 // only those) nodes should remain :active until the mouse is released. 6506 // only those) nodes should remain :active until the mouse is released.
6507 bool allow_active_changes = !old_active_element && ActiveHoverElement(); 6507 bool allow_active_changes = !old_active_element && ActiveHoverElement();
6508 6508
6509 // If the mouse is down and if this is a mouse move event, we want to restrict 6509 // If the mouse is down and if this is a mouse move event, we want to restrict
6510 // changes in :hover/:active to only apply to elements that are in the :active 6510 // changes in :active to only apply to elements that are in the :active
6511 // chain that we froze at the time the mouse went down. 6511 // chain that we froze at the time the mouse went down.
6512 bool must_be_in_active_chain = request.Active() && request.Move(); 6512 bool must_be_in_active_chain = request.Active() && request.Move();
6513 6513
6514 Element* old_hover_element = HoverElement(); 6514 Element* old_hover_element = HoverElement();
6515 6515
6516 // The passed in innerElement may not be a result of a hit test for the 6516 // The passed in innerElement may not be a result of a hit test for the
6517 // current up-to-date flat/layout tree. That means the element may be 6517 // current up-to-date flat/layout tree. That means the element may be
6518 // display:none at this point. Skip up the ancestor chain until we reach an 6518 // display:none at this point. Skip up the ancestor chain until we reach an
6519 // element with a layoutObject or a display:contents element. 6519 // element with a layoutObject or a display:contents element.
6520 Element* new_hover_element = 6520 Element* new_hover_element =
6521 SkipDisplayNoneAncestors(inner_element_in_document); 6521 SkipDisplayNoneAncestors(inner_element_in_document);
6522 6522
6523 // Update our current hover element. 6523 // Update our current hover element.
6524 if (allow_hover_changes) 6524 if (allow_hover_changes)
6525 SetHoverElement(new_hover_element); 6525 SetHoverElement(new_hover_element);
6526 6526
6527 Node* ancestor_element = nullptr; 6527 Node* ancestor_element = nullptr;
6528 if (old_hover_element && old_hover_element->isConnected() && 6528 if (old_hover_element && old_hover_element->isConnected() &&
6529 new_hover_element) { 6529 new_hover_element) {
6530 Node* ancestor = FlatTreeTraversal::CommonAncestor(*old_hover_element, 6530 Node* ancestor = FlatTreeTraversal::CommonAncestor(*old_hover_element,
6531 *new_hover_element); 6531 *new_hover_element);
6532 if (ancestor && ancestor->IsElementNode()) 6532 if (ancestor && ancestor->IsElementNode())
6533 ancestor_element = ToElement(ancestor); 6533 ancestor_element = ToElement(ancestor);
6534 } 6534 }
6535 6535
6536 HeapVector<Member<Element>, 32> elements_to_remove_from_chain; 6536 HeapVector<Member<Element>, 32> elements_to_remove_from_chain;
mustaq 2017/07/10 15:40:45 This asymmetric list for removal vs addition give
lanwei 2017/07/12 21:03:10 Done.
6537 HeapVector<Member<Element>, 32> elements_to_add_to_chain; 6537 HeapVector<Member<Element>, 32> elements_to_add_to_active_chain;
6538 HeapVector<Member<Element>, 32> elements_to_add_to_hover_chain;
6538 6539
6539 if (old_hover_element != new_hover_element) { 6540 if (old_hover_element != new_hover_element) {
6540 // The old hover path only needs to be cleared up to (and not including) the 6541 // The old hover path only needs to be cleared up to (and not including) the
6541 // common ancestor; 6542 // common ancestor;
6542 // 6543 //
6543 // FIXME(ecobos@igalia.com): oldHoverElement may be disconnected from the 6544 // FIXME(ecobos@igalia.com): oldHoverElement may be disconnected from the
6544 // tree already. This is due to our handling of m_hoverElement in 6545 // tree already. This is due to our handling of m_hoverElement in
6545 // hoveredElementDetached (which assumes all the parents are hovered) and 6546 // hoveredElementDetached (which assumes all the parents are hovered) and
6546 // mustBeInActiveChain (which makes this not hold). 6547 // mustBeInActiveChain (which makes this not hold).
Navid Zolghadr 2017/07/07 18:21:00 nit: I believe this comment also doesn't hold sinc
lanwei 2017/07/12 21:03:10 Done.
6547 //
6548 // In that case, none of the nodes in the chain have the flags, so there's
6549 // no problem in skipping this step.
6550 if (old_hover_element && old_hover_element->isConnected()) { 6548 if (old_hover_element && old_hover_element->isConnected()) {
6551 for (Element* curr = old_hover_element; curr && curr != ancestor_element; 6549 for (Element* curr = old_hover_element; curr && curr != ancestor_element;
6552 curr = FlatTreeTraversal::ParentElement(*curr)) { 6550 curr = FlatTreeTraversal::ParentElement(*curr)) {
6553 if (!must_be_in_active_chain || curr->InActiveChain()) 6551 elements_to_remove_from_chain.push_back(curr);
6554 elements_to_remove_from_chain.push_back(curr);
6555 } 6552 }
6556 } 6553 }
6557 } 6554 }
6558 6555
6559 // Now set the hover state for our new object up to the root. 6556 // Now set the hover state for our new object up to the root.
6560 for (Element* curr = new_hover_element; curr; 6557 for (Element* curr = new_hover_element; curr;
6561 curr = FlatTreeTraversal::ParentElement(*curr)) { 6558 curr = FlatTreeTraversal::ParentElement(*curr)) {
6559 if (old_hover_element != new_hover_element)
6560 elements_to_add_to_hover_chain.push_back(curr);
6562 if (!must_be_in_active_chain || curr->InActiveChain()) 6561 if (!must_be_in_active_chain || curr->InActiveChain())
6563 elements_to_add_to_chain.push_back(curr); 6562 elements_to_add_to_active_chain.push_back(curr);
6564 } 6563 }
6565 6564
6566 if (allow_hover_changes) { 6565 if (allow_hover_changes) {
6567 for (Element* element : elements_to_remove_from_chain) 6566 for (Element* element : elements_to_remove_from_chain)
6568 element->SetHovered(false); 6567 element->SetHovered(false);
6569 } 6568 }
6570 6569
6570 // Elements past the common ancestor do not change hover state, but might
6571 // change active state.
6572 for (Element* element : elements_to_add_to_active_chain) {
6573 if (allow_active_changes)
6574 element->SetActive(true);
6575 }
6576
6571 bool saw_common_ancestor = false; 6577 bool saw_common_ancestor = false;
6572 for (Element* element : elements_to_add_to_chain) { 6578 for (Element* element : elements_to_add_to_hover_chain) {
6573 // Elements past the common ancestor do not change hover state, but might
6574 // change active state.
6575 if (element == ancestor_element) 6579 if (element == ancestor_element)
6576 saw_common_ancestor = true; 6580 saw_common_ancestor = true;
6577 if (allow_active_changes)
6578 element->SetActive(true);
6579 if (allow_hover_changes && 6581 if (allow_hover_changes &&
6580 (!saw_common_ancestor || element == hover_element_)) 6582 (!saw_common_ancestor || element == hover_element_))
6581 element->SetHovered(true); 6583 element->SetHovered(true);
6582 } 6584 }
6583 } 6585 }
6584 6586
6585 bool Document::HaveScriptBlockingStylesheetsLoaded() const { 6587 bool Document::HaveScriptBlockingStylesheetsLoaded() const {
6586 return style_engine_->HaveScriptBlockingStylesheetsLoaded(); 6588 return style_engine_->HaveScriptBlockingStylesheetsLoaded();
6587 } 6589 }
6588 6590
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
6939 } 6941 }
6940 6942
6941 void showLiveDocumentInstances() { 6943 void showLiveDocumentInstances() {
6942 WeakDocumentSet& set = liveDocumentSet(); 6944 WeakDocumentSet& set = liveDocumentSet();
6943 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); 6945 fprintf(stderr, "There are %u documents currently alive:\n", set.size());
6944 for (blink::Document* document : set) 6946 for (blink::Document* document : set)
6945 fprintf(stderr, "- Document %p URL: %s\n", document, 6947 fprintf(stderr, "- Document %p URL: %s\n", document,
6946 document->Url().GetString().Utf8().data()); 6948 document->Url().GetString().Utf8().data());
6947 } 6949 }
6948 #endif 6950 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698