Skip to content

Commit

Permalink
Move LayoutObject ScrollIntoView to their own file
Browse files Browse the repository at this point in the history
These methods don't belong in LayoutObject/LayoutBox. Since we now have
scroll_into_view.cc these methods can be made into free-standing
functions. We also improve handling cases where the scroll is prevented
from bubbling.

The LayoutBox version was simply a helper used by LayoutObject so this
now becomes an implementation detail. Its one other caller was
LayoutBox::Autoscroll. Autoscroll is used when drag and drop or
selecting near a scroller's edge. The only difference between the two
calls is that LayoutObject sets up a "sequenced scroll" which is used to
animate multiple scrollers. Since Autoscroll doesn't use an animation
this change is a no-op.

PS2 moves the methods into scroll_into_view.cc. Compare PS2 to latest PS
to see new diffs.

Bug: 1296183
Change-Id: I62d3a6aff34815f8d8cb8e0688c05a43a1460932
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3615931
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: David Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1001017}
  • Loading branch information
bokand authored and Chromium LUCI CQ committed May 9, 2022
1 parent c470d55 commit 5202982
Show file tree
Hide file tree
Showing 19 changed files with 301 additions and 255 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/scroll/scroll_alignment.h"
#include "third_party/blink/renderer/core/scroll/scroll_into_view_util.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
Expand Down Expand Up @@ -135,8 +136,8 @@ void AnnotationAgentImpl::ScrollIntoView() {
mojom::blink::ScrollType::kProgrammatic);
params->cross_origin_boundaries = false;

first_node.GetLayoutObject()->ScrollRectToVisible(bounding_box,
std::move(params));
scroll_into_view_util::ScrollRectToVisible(*first_node.GetLayoutObject(),
bounding_box, std::move(params));
}

void AnnotationAgentImpl::DidFinishAttach(const RangeInFlatTree* range) {
Expand Down
27 changes: 16 additions & 11 deletions third_party/blink/renderer/core/dom/element.cc
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observation.h"
#include "third_party/blink/renderer/core/scroll/scroll_into_view_util.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
Expand Down Expand Up @@ -1222,7 +1223,8 @@ void Element::ScrollIntoViewNoVisualUpdate(
}

PhysicalRect bounds = BoundingBoxForScrollIntoView();
GetLayoutObject()->ScrollRectToVisible(bounds, std::move(params));
scroll_into_view_util::ScrollRectToVisible(*GetLayoutObject(), bounds,
std::move(params));

GetDocument().SetSequentialFocusNavigationStartingPoint(this);
}
Expand All @@ -1236,15 +1238,17 @@ void Element::scrollIntoViewIfNeeded(bool center_if_needed) {

PhysicalRect bounds = BoundingBoxForScrollIntoView();
if (center_if_needed) {
GetLayoutObject()->ScrollRectToVisible(
bounds, ScrollAlignment::CreateScrollIntoViewParams(
ScrollAlignment::CenterIfNeeded(),
ScrollAlignment::CenterIfNeeded()));
scroll_into_view_util::ScrollRectToVisible(
*GetLayoutObject(), bounds,
ScrollAlignment::CreateScrollIntoViewParams(
ScrollAlignment::CenterIfNeeded(),
ScrollAlignment::CenterIfNeeded()));
} else {
GetLayoutObject()->ScrollRectToVisible(
bounds, ScrollAlignment::CreateScrollIntoViewParams(
ScrollAlignment::ToEdgeIfNeeded(),
ScrollAlignment::ToEdgeIfNeeded()));
scroll_into_view_util::ScrollRectToVisible(
*GetLayoutObject(), bounds,
ScrollAlignment::CreateScrollIntoViewParams(
ScrollAlignment::ToEdgeIfNeeded(),
ScrollAlignment::ToEdgeIfNeeded()));
}
}

Expand Down Expand Up @@ -5229,8 +5233,9 @@ void Element::UpdateSelectionOnFocus(
params->align_x->rect_partial =
mojom::blink::ScrollAlignment::Behavior::kNoScroll;

GetLayoutObject()->ScrollRectToVisible(BoundingBoxForScrollIntoView(),
std::move(params));
scroll_into_view_util::ScrollRectToVisible(*GetLayoutObject(),
BoundingBoxForScrollIntoView(),
std::move(params));
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions third_party/blink/renderer/core/editing/finder/text_finder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/text_autosizer.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/scroll/scroll_into_view_util.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/timer.h"

Expand Down Expand Up @@ -168,8 +169,8 @@ static void ScrollToVisible(Range* match) {
mojom::blink::ScrollBehavior scroll_behavior =
smooth_find_enabled ? mojom::blink::ScrollBehavior::kSmooth
: mojom::blink::ScrollBehavior::kAuto;
first_node.GetLayoutObject()->ScrollRectToVisible(
PhysicalRect(match->BoundingBox()),
scroll_into_view_util::ScrollRectToVisible(
*first_node.GetLayoutObject(), PhysicalRect(match->BoundingBox()),
ScrollAlignment::CreateScrollIntoViewParams(
ScrollAlignment::CenterIfNeeded(), ScrollAlignment::CenterIfNeeded(),
mojom::blink::ScrollType::kUser,
Expand Down Expand Up @@ -795,7 +796,8 @@ int TextFinder::SelectFindMatch(unsigned index, gfx::Rect* selection_rect) {
if (!active_match_bounding_box.IsEmpty()) {
if (active_match_->FirstNode() &&
active_match_->FirstNode()->GetLayoutObject()) {
active_match_->FirstNode()->GetLayoutObject()->ScrollRectToVisible(
scroll_into_view_util::ScrollRectToVisible(
*active_match_->FirstNode()->GetLayoutObject(),
PhysicalRect(active_match_bounding_box),
ScrollAlignment::CreateScrollIntoViewParams(
ScrollAlignment::CenterIfNeeded(),
Expand Down
5 changes: 3 additions & 2 deletions third_party/blink/renderer/core/editing/frame_selection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
#include "third_party/blink/renderer/core/page/page_animator.h"
#include "third_party/blink/renderer/core/page/spatial_navigation.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/scroll/scroll_into_view_util.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
Expand Down Expand Up @@ -1088,8 +1089,8 @@ void FrameSelection::RevealSelection(
!start.AnchorNode()->GetLayoutObject()->EnclosingBox())
return;

start.AnchorNode()->GetLayoutObject()->ScrollRectToVisible(
selection_rect,
scroll_into_view_util::ScrollRectToVisible(
*start.AnchorNode()->GetLayoutObject(), selection_rect,
ScrollAlignment::CreateScrollIntoViewParams(alignment, alignment));
UpdateAppearance();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/scroll/scroll_alignment.h"
#include "third_party/blink/renderer/core/scroll/scroll_into_view_util.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/search_engine_utils.h"

Expand Down Expand Up @@ -378,8 +379,8 @@ void TextFragmentAnchor::DidFindMatch(const RangeInFlatTree& range,
ScrollAlignment::CenterAlways(), ScrollAlignment::CenterAlways(),
mojom::blink::ScrollType::kProgrammatic);
params->cross_origin_boundaries = false;
first_node.GetLayoutObject()->ScrollRectToVisible(bounding_box,
std::move(params));
scroll_into_view_util::ScrollRectToVisible(*first_node.GetLayoutObject(),
bounding_box, std::move(params));
did_scroll_into_view_ = true;

if (AXObjectCache* cache = frame_->GetDocument()->ExistingAXObjectCache())
Expand Down
3 changes: 2 additions & 1 deletion third_party/blink/renderer/core/frame/remote_frame.cc
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,8 @@ void RemoteFrame::ScrollRectToVisible(
PhysicalRect absolute_rect = owner_object->LocalToAncestorRect(
PhysicalRect::EnclosingRect(rect_to_scroll), owner_object->View());

owner_object->ScrollRectToVisible(absolute_rect, std::move(params));
scroll_into_view_util::ScrollRectToVisible(*owner_object, absolute_rect,
std::move(params));
}

void RemoteFrame::IntrinsicSizingInfoOfChildChanged(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
#include "third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h"
#include "third_party/blink/renderer/core/paint/paint_timing_detector.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/scroll/scroll_into_view_util.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
Expand Down Expand Up @@ -1967,8 +1968,8 @@ bool WebFrameWidgetImpl::ScrollFocusedEditableElementIntoView() {
params->for_focused_editable->relative_location = editable_offset_from_caret;
params->for_focused_editable->size = editable_size;

element->GetLayoutObject()->ScrollRectToVisible(absolute_caret_bounds,
std::move(params));
scroll_into_view_util::ScrollRectToVisible(
*element->GetLayoutObject(), absolute_caret_bounds, std::move(params));

return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/scroll/scroll_into_view_util.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/to_v8.h"
Expand Down Expand Up @@ -341,8 +342,8 @@ void HTMLInputElement::UpdateSelectionOnFocus(
this, DocumentUpdateReason::kFocus);
if (!options->preventScroll()) {
if (GetLayoutObject()) {
GetLayoutObject()->ScrollRectToVisible(
BoundingBoxForScrollIntoView(),
scroll_into_view_util::ScrollRectToVisible(
*GetLayoutObject(), BoundingBoxForScrollIntoView(),
ScrollAlignment::CreateScrollIntoViewParams());
}
if (GetDocument().GetFrame())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/page/frame_tree.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/scroll/scroll_into_view_util.h"
#include "third_party/blink/renderer/core/svg/svg_svg_element.h"
#include "third_party/blink/renderer/core/xml/document_xpath_evaluator.h"
#include "third_party/blink/renderer/core/xml/xpath_result.h"
Expand Down Expand Up @@ -2516,8 +2517,8 @@ protocol::Response InspectorDOMAgent::scrollIntoViewIfNeeded(
rect_to_scroll.SetWidth(LayoutUnit(rect.fromJust()->getWidth()));
rect_to_scroll.SetHeight(LayoutUnit(rect.fromJust()->getHeight()));
}
layout_object->ScrollRectToVisible(
rect_to_scroll,
scroll_into_view_util::ScrollRectToVisible(
*layout_object, rect_to_scroll,
ScrollAlignment::CreateScrollIntoViewParams(
ScrollAlignment::CenterIfNeeded(), ScrollAlignment::CenterIfNeeded(),
mojom::blink::ScrollType::kProgrammatic,
Expand Down
132 changes: 3 additions & 129 deletions third_party/blink/renderer/core/layout/layout_box.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,13 @@
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_opt_group_element.h"
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h"
#include "third_party/blink/renderer/core/html/shadow/shadow_element_utils.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
Expand Down Expand Up @@ -1145,131 +1143,6 @@ int LayoutBox::PixelSnappedScrollHeight() const {
return SnapSizeToPixel(ScrollHeight(), Location().Y() + ClientTop());
}

LayoutBox* LayoutBox::GetScrollParent(
const mojom::blink::ScrollIntoViewParamsPtr& params) {
NOT_DESTROYED();

bool is_fixed_to_frame =
StyleRef().GetPosition() == EPosition::kFixed && Container() == View();

// Within a document scrolls bubble along the containing block chain but if
// we're in a position:fixed element, we want to immediately bubble up across
// the frame boundary since scrolling the frame won't affect the box's
// position.
if (ContainingBlock() && !is_fixed_to_frame)
return ContainingBlock();

// Otherwise, we're bubbling across a frame boundary. We may be
// prevented from doing so for security or policy reasons. If so, we're
// done.
if (!GetFrame()->View()->AllowedToPropagateScrollIntoView(params))
return nullptr;

if (!GetFrame()->IsLocalRoot()) {
// The parent is a local iframe, convert to the absolute coordinate space
// of its document and continue from the owner's LayoutBox.
HTMLFrameOwnerElement* owner_element = GetDocument().LocalOwner();
DCHECK(owner_element);

// A display:none iframe can have a LayoutView but its owner element won't
// have a LayoutObject. If that happens, don't bubble the scroll.
if (!owner_element->GetLayoutObject())
return nullptr;

return owner_element->GetLayoutObject()->EnclosingBox();
}

// If the owner is remote, the scroll must continue via IPC.
DCHECK(GetFrame()->IsMainFrame() || GetFrame()->Parent()->IsRemoteFrame());
return nullptr;
}

PhysicalRect LayoutBox::ScrollRectToVisibleLocally(
const PhysicalRect& absolute_rect,
mojom::blink::ScrollIntoViewParamsPtr& params) {
NOT_DESTROYED();
DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
params->type == mojom::blink::ScrollType::kUser);

if (!GetFrameView())
return absolute_rect;

LayoutBox* current_box = this;
PhysicalRect absolute_rect_to_scroll = absolute_rect;

while (current_box) {
if (absolute_rect_to_scroll.Width() <= 0)
absolute_rect_to_scroll.SetWidth(LayoutUnit(1));
if (absolute_rect_to_scroll.Height() <= 0)
absolute_rect_to_scroll.SetHeight(LayoutUnit(1));

// If we've reached the main frame's layout viewport (which is always set to
// the global root scroller, see ViewportScrollCallback::SetScroller), abort
// if the stop_at_main_frame_layout_viewport option is set. We do this so
// that we can allow a smooth "scroll and zoom" animation to do the final
// scroll in cases like scrolling a focused editable box into view.
// TODO(bokan): This may need to account for fenced frames.
// https://crbug.com/1314858
if (params->for_focused_editable && current_box->IsGlobalRootScroller())
break;

ScrollableArea* area_to_scroll = nullptr;

if (current_box->IsScrollContainer() && !IsA<LayoutView>(current_box)) {
area_to_scroll = current_box->GetScrollableArea();
} else if (!current_box->ContainingBlock()) {
area_to_scroll = params->make_visible_in_visual_viewport
? current_box->GetFrameView()->GetScrollableArea()
: current_box->GetFrameView()->LayoutViewport();
}

if (area_to_scroll) {
absolute_rect_to_scroll =
area_to_scroll->ScrollIntoView(absolute_rect_to_scroll, params);
}

bool is_fixed_to_frame =
current_box->StyleRef().GetPosition() == EPosition::kFixed &&
current_box->Container() == current_box->View();

if (is_fixed_to_frame && current_box->GetFrame()->IsMainFrame() &&
params->make_visible_in_visual_viewport) {
// If we're in a position:fixed element, scrolling the layout viewport
// won't have any effect and would be wrong so we want to bubble up to
// the layout viewport's parent. For subframes that's the frame's owner.
// For the main frame that's the visual viewport but it isn't associated
// with a LayoutBox so we just scroll it here as a special case.
// Note: In non-fixed cases, the visual viewport will have been scrolled
// by the frame scroll via the RootFrameViewport
// (GetFrameView()->GetScrollableArea() above).
absolute_rect_to_scroll =
current_box->GetFrame()
->GetPage()
->GetVisualViewport()
.ScrollIntoView(absolute_rect_to_scroll, params);
break;
}

LayoutBox* next_box = current_box->GetScrollParent(params);

// If the next box to scroll is in another frame, we need to convert the
// scroll box to the new frame's absolute coordinates.
if (next_box && next_box->View() != current_box->View()) {
scroll_into_view_util::ConvertParamsToParentFrame(
params, gfx::RectF(absolute_rect_to_scroll), *current_box->View(),
*next_box->View());

absolute_rect_to_scroll = current_box->View()->LocalToAncestorRect(
absolute_rect_to_scroll, next_box->View(),
kTraverseDocumentBoundaries);
}

current_box = next_box;
}

return absolute_rect_to_scroll;
}

void LayoutBox::SetMargin(const NGPhysicalBoxStrut& box) {
NOT_DESTROYED();
margin_box_outsets_.SetTop(box.top);
Expand Down Expand Up @@ -1883,10 +1756,11 @@ void LayoutBox::Autoscroll(const PhysicalOffset& position_in_root_frame) {
ScrollAlignment::CreateScrollIntoViewParams(
ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
mojom::blink::ScrollType::kUser);
ScrollRectToVisibleLocally(
scroll_into_view_util::ScrollRectToVisible(
*this,
PhysicalRect(absolute_position,
PhysicalSize(LayoutUnit(1), LayoutUnit(1))),
params);
std::move(params));
}

// If specified point is outside the border-belt-excluded box (the border box
Expand Down

0 comments on commit 5202982

Please sign in to comment.