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 | 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 2612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2623 | 2623 |
2624 if (layout_view_) | 2624 if (layout_view_) |
2625 layout_view_->SetIsInWindow(false); | 2625 layout_view_->SetIsInWindow(false); |
2626 | 2626 |
2627 if (RegistrationContext()) | 2627 if (RegistrationContext()) |
2628 RegistrationContext()->DocumentWasDetached(); | 2628 RegistrationContext()->DocumentWasDetached(); |
2629 | 2629 |
2630 MutationObserver::CleanSlotChangeList(*this); | 2630 MutationObserver::CleanSlotChangeList(*this); |
2631 | 2631 |
2632 hover_element_ = nullptr; | 2632 hover_element_ = nullptr; |
2633 active_hover_element_ = nullptr; | 2633 active_element_ = nullptr; |
2634 autofocus_element_ = nullptr; | 2634 autofocus_element_ = nullptr; |
2635 | 2635 |
2636 if (focused_element_.Get()) { | 2636 if (focused_element_.Get()) { |
2637 Element* old_focused_element = focused_element_; | 2637 Element* old_focused_element = focused_element_; |
2638 focused_element_ = nullptr; | 2638 focused_element_ = nullptr; |
2639 if (GetPage()) | 2639 if (GetPage()) |
2640 GetPage()->GetChromeClient().FocusedNodeChanged(old_focused_element, | 2640 GetPage()->GetChromeClient().FocusedNodeChanged(old_focused_element, |
2641 nullptr); | 2641 nullptr); |
2642 } | 2642 } |
2643 sequential_focus_navigation_starting_point_ = nullptr; | 2643 sequential_focus_navigation_starting_point_ = nullptr; |
(...skipping 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4180 DCHECK(!GetLayoutViewItem().IsNull() || ImportsController()); | 4180 DCHECK(!GetLayoutViewItem().IsNull() || ImportsController()); |
4181 if (!GetLayoutViewItem().IsNull()) | 4181 if (!GetLayoutViewItem().IsNull()) |
4182 GetLayoutViewItem().InvalidatePaintForViewAndCompositedLayers(); | 4182 GetLayoutViewItem().InvalidatePaintForViewAndCompositedLayers(); |
4183 } | 4183 } |
4184 } | 4184 } |
4185 | 4185 |
4186 void Document::SetHoverElement(Element* new_hover_element) { | 4186 void Document::SetHoverElement(Element* new_hover_element) { |
4187 hover_element_ = new_hover_element; | 4187 hover_element_ = new_hover_element; |
4188 } | 4188 } |
4189 | 4189 |
4190 void Document::SetActiveHoverElement(Element* new_active_element) { | 4190 void Document::SetActiveElement(Element* new_active_element) { |
4191 if (!new_active_element) { | 4191 if (!new_active_element) { |
4192 active_hover_element_.Clear(); | 4192 active_element_.Clear(); |
4193 return; | 4193 return; |
4194 } | 4194 } |
4195 | 4195 |
4196 active_hover_element_ = new_active_element; | 4196 active_element_ = new_active_element; |
4197 } | 4197 } |
4198 | 4198 |
4199 void Document::RemoveFocusedElementOfSubtree(Node* node, | 4199 void Document::RemoveFocusedElementOfSubtree(Node* node, |
4200 bool among_children_only) { | 4200 bool among_children_only) { |
4201 if (!focused_element_) | 4201 if (!focused_element_) |
4202 return; | 4202 return; |
4203 | 4203 |
4204 // We can't be focused if we're not in the document. | 4204 // We can't be focused if we're not in the document. |
4205 if (!node->isConnected()) | 4205 if (!node->isConnected()) |
4206 return; | 4206 return; |
(...skipping 24 matching lines...) Expand all Loading... |
4231 // hover effects on the ancestors of |element| and do not invoke | 4231 // hover effects on the ancestors of |element| and do not invoke |
4232 // new hover effects on any other element. | 4232 // new hover effects on any other element. |
4233 if (!GetPage()->IsCursorVisible()) | 4233 if (!GetPage()->IsCursorVisible()) |
4234 return; | 4234 return; |
4235 | 4235 |
4236 if (GetFrame()) | 4236 if (GetFrame()) |
4237 GetFrame()->GetEventHandler().ScheduleHoverStateUpdate(); | 4237 GetFrame()->GetEventHandler().ScheduleHoverStateUpdate(); |
4238 } | 4238 } |
4239 | 4239 |
4240 void Document::ActiveChainNodeDetached(Element& element) { | 4240 void Document::ActiveChainNodeDetached(Element& element) { |
4241 if (element == active_hover_element_) | 4241 if (element == active_element_) |
4242 active_hover_element_ = SkipDisplayNoneAncestors(&element); | 4242 active_element_ = SkipDisplayNoneAncestors(&element); |
4243 } | 4243 } |
4244 | 4244 |
4245 const Vector<AnnotatedRegionValue>& Document::AnnotatedRegions() const { | 4245 const Vector<AnnotatedRegionValue>& Document::AnnotatedRegions() const { |
4246 return annotated_regions_; | 4246 return annotated_regions_; |
4247 } | 4247 } |
4248 | 4248 |
4249 void Document::SetAnnotatedRegions( | 4249 void Document::SetAnnotatedRegions( |
4250 const Vector<AnnotatedRegionValue>& regions) { | 4250 const Vector<AnnotatedRegionValue>& regions) { |
4251 annotated_regions_ = regions; | 4251 annotated_regions_ = regions; |
4252 SetAnnotatedRegionsDirty(false); | 4252 SetAnnotatedRegionsDirty(false); |
(...skipping 2211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 |
| 6475 UpdateActiveState(request, inner_element_in_document); |
| 6476 UpdateHoverState(request, inner_element_in_document); |
| 6477 } |
| 6478 |
| 6479 void Document::UpdateActiveState(const HitTestRequest& request, |
| 6480 Element* inner_element_in_document) { |
| 6481 Element* old_active_element = GetActiveElement(); |
6475 if (old_active_element && !request.Active()) { | 6482 if (old_active_element && !request.Active()) { |
6476 // The oldActiveElement layoutObject is null, dropped on :active by setting | 6483 // The oldActiveElement layoutObject is null, dropped on :active by setting |
6477 // display: none, for instance. We still need to clear the ActiveChain as | 6484 // display: none, for instance. We still need to clear the ActiveChain as |
6478 // the mouse is released. | 6485 // the mouse is released. |
6479 for (Element* element = old_active_element; element; | 6486 for (Element* element = old_active_element; element; |
6480 element = FlatTreeTraversal::ParentElement(*element)) { | 6487 element = FlatTreeTraversal::ParentElement(*element)) { |
6481 element->SetActive(false); | 6488 element->SetActive(false); |
6482 user_action_elements_.SetInActiveChain(element, false); | 6489 user_action_elements_.SetInActiveChain(element, false); |
6483 } | 6490 } |
6484 SetActiveHoverElement(nullptr); | 6491 SetActiveElement(nullptr); |
6485 } else { | 6492 } else { |
6486 Element* new_active_element = inner_element_in_document; | 6493 Element* new_active_element = inner_element_in_document; |
6487 if (!old_active_element && new_active_element && | 6494 if (!old_active_element && new_active_element && |
6488 !new_active_element->IsDisabledFormControl() && request.Active() && | 6495 !new_active_element->IsDisabledFormControl() && request.Active() && |
6489 !request.TouchMove()) { | 6496 !request.TouchMove()) { |
6490 // We are setting the :active chain and freezing it. If future moves | 6497 // We are setting the :active chain and freezing it. If future moves |
6491 // happen, they will need to reference this chain. | 6498 // happen, they will need to reference this chain. |
6492 for (Element* element = new_active_element; element; | 6499 for (Element* element = new_active_element; element; |
6493 element = FlatTreeTraversal::ParentElement(*element)) { | 6500 element = FlatTreeTraversal::ParentElement(*element)) { |
6494 user_action_elements_.SetInActiveChain(element, true); | 6501 user_action_elements_.SetInActiveChain(element, true); |
6495 } | 6502 } |
6496 SetActiveHoverElement(new_active_element); | 6503 SetActiveElement(new_active_element); |
6497 } | 6504 } |
6498 } | 6505 } |
6499 | 6506 |
| 6507 // If the mouse has just been pressed, set :active on the chain. Those (and |
| 6508 // only those) nodes should remain :active until the mouse is released. |
| 6509 bool allow_active_changes = !old_active_element && GetActiveElement(); |
| 6510 if (!allow_active_changes) |
| 6511 return; |
| 6512 |
| 6513 // If the mouse is down and if this is a mouse move event, we want to restrict |
| 6514 // changes in :active to only apply to elements that are in the :active |
| 6515 // chain that we froze at the time the mouse went down. |
| 6516 bool must_be_in_active_chain = request.Active() && request.Move(); |
| 6517 |
| 6518 Element* new_element = |
| 6519 SkipDisplayNoneAncestors(inner_element_in_document); |
| 6520 |
| 6521 // Now set the active state for our new object up to the root. |
| 6522 for (Element* curr = new_element; curr; |
| 6523 curr = FlatTreeTraversal::ParentElement(*curr)) { |
| 6524 if (!must_be_in_active_chain || curr->InActiveChain()) |
| 6525 curr->SetActive(true); |
| 6526 } |
| 6527 } |
| 6528 |
| 6529 void Document::UpdateHoverState(const HitTestRequest& request, |
| 6530 Element* inner_element_in_document) { |
6500 // Do not set hover state if event is from touch and on mobile. | 6531 // Do not set hover state if event is from touch and on mobile. |
6501 bool allow_hover_changes = | 6532 bool allow_hover_changes = |
6502 !(request.TouchEvent() && GetPage() && | 6533 !(request.TouchEvent() && GetPage() && |
6503 GetPage()->GetVisualViewport().ShouldDisableDesktopWorkarounds()); | 6534 GetPage()->GetVisualViewport().ShouldDisableDesktopWorkarounds()); |
6504 | 6535 |
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. | |
6507 bool allow_active_changes = !old_active_element && ActiveHoverElement(); | |
6508 | |
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 | |
6511 // chain that we froze at the time the mouse went down. | |
6512 bool must_be_in_active_chain = request.Active() && request.Move(); | |
6513 | |
6514 Element* old_hover_element = HoverElement(); | 6536 Element* old_hover_element = HoverElement(); |
6515 | 6537 |
6516 // The passed in innerElement may not be a result of a hit test for the | 6538 // 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 | 6539 // 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 | 6540 // display:none at this point. Skip up the ancestor chain until we reach an |
6519 // element with a layoutObject or a display:contents element. | 6541 // element with a layoutObject or a display:contents element. |
6520 Element* new_hover_element = | 6542 Element* new_hover_element = |
6521 SkipDisplayNoneAncestors(inner_element_in_document); | 6543 SkipDisplayNoneAncestors(inner_element_in_document); |
6522 | 6544 |
6523 // Update our current hover element. | 6545 // Update our current hover element. |
6524 if (allow_hover_changes) | 6546 if (allow_hover_changes) |
6525 SetHoverElement(new_hover_element); | 6547 SetHoverElement(new_hover_element); |
6526 | 6548 |
| 6549 if (old_hover_element == new_hover_element || !allow_hover_changes) |
| 6550 return; |
| 6551 |
6527 Node* ancestor_element = nullptr; | 6552 Node* ancestor_element = nullptr; |
6528 if (old_hover_element && old_hover_element->isConnected() && | 6553 if (old_hover_element && old_hover_element->isConnected() && |
6529 new_hover_element) { | 6554 new_hover_element) { |
6530 Node* ancestor = FlatTreeTraversal::CommonAncestor(*old_hover_element, | 6555 Node* ancestor = FlatTreeTraversal::CommonAncestor(*old_hover_element, |
6531 *new_hover_element); | 6556 *new_hover_element); |
6532 if (ancestor && ancestor->IsElementNode()) | 6557 if (ancestor && ancestor->IsElementNode()) |
6533 ancestor_element = ToElement(ancestor); | 6558 ancestor_element = ToElement(ancestor); |
6534 } | 6559 } |
6535 | 6560 |
6536 HeapVector<Member<Element>, 32> elements_to_remove_from_chain; | 6561 HeapVector<Member<Element>, 32> elements_to_remove_from_chain; |
6537 HeapVector<Member<Element>, 32> elements_to_add_to_chain; | 6562 HeapVector<Member<Element>, 32> elements_to_add_to_hover_chain; |
6538 | 6563 |
6539 if (old_hover_element != new_hover_element) { | 6564 // The old hover path only needs to be cleared up to (and not including) the |
6540 // The old hover path only needs to be cleared up to (and not including) the | 6565 // common ancestor; |
6541 // common ancestor; | 6566 // |
6542 // | 6567 // FIXME(ecobos@igalia.com): oldHoverElement may be disconnected from the |
6543 // FIXME(ecobos@igalia.com): oldHoverElement may be disconnected from the | 6568 // tree already. |
6544 // tree already. This is due to our handling of m_hoverElement in | 6569 if (old_hover_element && old_hover_element->isConnected()) { |
6545 // hoveredElementDetached (which assumes all the parents are hovered) and | 6570 for (Element* curr = old_hover_element; curr && curr != ancestor_element; |
6546 // mustBeInActiveChain (which makes this not hold). | 6571 curr = FlatTreeTraversal::ParentElement(*curr)) { |
6547 // | 6572 elements_to_remove_from_chain.push_back(curr); |
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()) { | |
6551 for (Element* curr = old_hover_element; curr && curr != ancestor_element; | |
6552 curr = FlatTreeTraversal::ParentElement(*curr)) { | |
6553 if (!must_be_in_active_chain || curr->InActiveChain()) | |
6554 elements_to_remove_from_chain.push_back(curr); | |
6555 } | |
6556 } | 6573 } |
6557 } | 6574 } |
6558 | 6575 |
6559 // Now set the hover state for our new object up to the root. | 6576 // Now set the hover state for our new object up to the root. |
6560 for (Element* curr = new_hover_element; curr; | 6577 for (Element* curr = new_hover_element; curr; |
6561 curr = FlatTreeTraversal::ParentElement(*curr)) { | 6578 curr = FlatTreeTraversal::ParentElement(*curr)) { |
6562 if (!must_be_in_active_chain || curr->InActiveChain()) | 6579 elements_to_add_to_hover_chain.push_back(curr); |
6563 elements_to_add_to_chain.push_back(curr); | |
6564 } | 6580 } |
6565 | 6581 |
6566 if (allow_hover_changes) { | 6582 for (Element* element : elements_to_remove_from_chain) |
6567 for (Element* element : elements_to_remove_from_chain) | 6583 element->SetHovered(false); |
6568 element->SetHovered(false); | |
6569 } | |
6570 | 6584 |
6571 bool saw_common_ancestor = false; | 6585 bool saw_common_ancestor = false; |
6572 for (Element* element : elements_to_add_to_chain) { | 6586 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) | 6587 if (element == ancestor_element) |
6576 saw_common_ancestor = true; | 6588 saw_common_ancestor = true; |
6577 if (allow_active_changes) | 6589 if (!saw_common_ancestor || element == hover_element_) |
6578 element->SetActive(true); | |
6579 if (allow_hover_changes && | |
6580 (!saw_common_ancestor || element == hover_element_)) | |
6581 element->SetHovered(true); | 6590 element->SetHovered(true); |
6582 } | 6591 } |
6583 } | 6592 } |
6584 | 6593 |
6585 bool Document::HaveScriptBlockingStylesheetsLoaded() const { | 6594 bool Document::HaveScriptBlockingStylesheetsLoaded() const { |
6586 return style_engine_->HaveScriptBlockingStylesheetsLoaded(); | 6595 return style_engine_->HaveScriptBlockingStylesheetsLoaded(); |
6587 } | 6596 } |
6588 | 6597 |
6589 bool Document::HaveRenderBlockingStylesheetsLoaded() const { | 6598 bool Document::HaveRenderBlockingStylesheetsLoaded() const { |
6590 if (RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled()) | 6599 if (RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled()) |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6832 } | 6841 } |
6833 | 6842 |
6834 DEFINE_TRACE(Document) { | 6843 DEFINE_TRACE(Document) { |
6835 visitor->Trace(imports_controller_); | 6844 visitor->Trace(imports_controller_); |
6836 visitor->Trace(doc_type_); | 6845 visitor->Trace(doc_type_); |
6837 visitor->Trace(implementation_); | 6846 visitor->Trace(implementation_); |
6838 visitor->Trace(autofocus_element_); | 6847 visitor->Trace(autofocus_element_); |
6839 visitor->Trace(focused_element_); | 6848 visitor->Trace(focused_element_); |
6840 visitor->Trace(sequential_focus_navigation_starting_point_); | 6849 visitor->Trace(sequential_focus_navigation_starting_point_); |
6841 visitor->Trace(hover_element_); | 6850 visitor->Trace(hover_element_); |
6842 visitor->Trace(active_hover_element_); | 6851 visitor->Trace(active_element_); |
6843 visitor->Trace(document_element_); | 6852 visitor->Trace(document_element_); |
6844 visitor->Trace(root_scroller_controller_); | 6853 visitor->Trace(root_scroller_controller_); |
6845 visitor->Trace(title_element_); | 6854 visitor->Trace(title_element_); |
6846 visitor->Trace(ax_object_cache_); | 6855 visitor->Trace(ax_object_cache_); |
6847 visitor->Trace(markers_); | 6856 visitor->Trace(markers_); |
6848 visitor->Trace(css_target_); | 6857 visitor->Trace(css_target_); |
6849 visitor->Trace(current_script_stack_); | 6858 visitor->Trace(current_script_stack_); |
6850 visitor->Trace(script_runner_); | 6859 visitor->Trace(script_runner_); |
6851 visitor->Trace(lists_invalidated_at_document_); | 6860 visitor->Trace(lists_invalidated_at_document_); |
6852 for (int i = 0; i < kNumNodeListInvalidationTypes; ++i) | 6861 for (int i = 0; i < kNumNodeListInvalidationTypes; ++i) |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6939 } | 6948 } |
6940 | 6949 |
6941 void showLiveDocumentInstances() { | 6950 void showLiveDocumentInstances() { |
6942 WeakDocumentSet& set = liveDocumentSet(); | 6951 WeakDocumentSet& set = liveDocumentSet(); |
6943 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); | 6952 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); |
6944 for (blink::Document* document : set) | 6953 for (blink::Document* document : set) |
6945 fprintf(stderr, "- Document %p URL: %s\n", document, | 6954 fprintf(stderr, "- Document %p URL: %s\n", document, |
6946 document->Url().GetString().Utf8().data()); | 6955 document->Url().GetString().Utf8().data()); |
6947 } | 6956 } |
6948 #endif | 6957 #endif |
OLD | NEW |