blob: 247613a72a852f03d4a28982314b0d99917b8971 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/page/autoscroll_controller.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
namespace blink {
class AutoscrollControllerTest : public SimTest {
public:
AutoscrollController& GetAutoscrollController() {
return WebView().GetPage()->GetAutoscrollController();
}
};
// Ensure Autoscroll not crash by layout called in UpdateSelectionForMouseDrag.
TEST_F(AutoscrollControllerTest,
CrashWhenLayoutStopAnimationBeforeScheduleAnimation) {
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
WebView().SetBaseBackgroundColorOverride(SK_ColorTRANSPARENT);
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
<!DOCTYPE html>
<style>
#scrollable {
overflow: auto;
width: 10px;
height: 10px;
}
</style>
<div id='scrollable'>
<p id='p'>Some text here for selection autoscroll.</p>
<p>Some text here for selection autoscroll.</p>
<p>Some text here for selection autoscroll.</p>
<p>Some text here for selection autoscroll.</p>
<p>Some text here for selection autoscroll.</p>
<p>Some text here for selection autoscroll.</p>
<p>Some text here for selection autoscroll.</p>
<p>Some text here for selection autoscroll.</p>
</div>
)HTML");
Compositor().BeginFrame();
AutoscrollController& controller = GetAutoscrollController();
Document& document = GetDocument();
Element* scrollable = document.getElementById("scrollable");
DCHECK(scrollable);
DCHECK(scrollable->GetLayoutObject());
WebMouseEvent event(WebInputEvent::Type::kMouseDown, gfx::PointF(5, 5),
gfx::PointF(5, 5), WebPointerProperties::Button::kLeft, 0,
WebInputEvent::Modifiers::kLeftButtonDown,
base::TimeTicks::Now());
event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(event);
controller.StartAutoscrollForSelection(scrollable->GetLayoutObject());
DCHECK(controller.IsAutoscrolling());
// Hide scrollable here will cause UpdateSelectionForMouseDrag stop animation.
scrollable->SetInlineStyleProperty(CSSPropertyID::kDisplay,
CSSValueID::kNone);
// BeginFrame will call AutoscrollController::Animate.
Compositor().BeginFrame();
EXPECT_FALSE(controller.IsAutoscrolling());
}
// Ensure that autoscrolling continues when the MouseLeave event is fired.
TEST_F(AutoscrollControllerTest, ContinueAutoscrollAfterMouseLeaveEvent) {
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
<!DOCTYPE html>
<style>
#scrollable {
width: 820px;
height: 620px;
}
</style>
<div id='scrollable'></div>
)HTML");
Compositor().BeginFrame();
AutoscrollController& controller = GetAutoscrollController();
EXPECT_FALSE(controller.IsAutoscrolling());
LocalFrame* frame = GetDocument().GetFrame();
Node* document_node = GetDocument().documentElement();
controller.StartMiddleClickAutoscroll(
frame, document_node->parentNode()->GetLayoutBox(), FloatPoint(),
FloatPoint());
EXPECT_TRUE(controller.IsAutoscrolling());
WebMouseEvent mouse_leave_event(WebInputEvent::Type::kMouseLeave,
WebInputEvent::kNoModifiers,
base::TimeTicks::Now());
mouse_leave_event.SetFrameScale(1);
frame->GetEventHandler().HandleMouseLeaveEvent(mouse_leave_event);
EXPECT_TRUE(controller.IsAutoscrolling());
}
// Ensure that autoscrolling stops when scrolling is no longer available.
TEST_F(AutoscrollControllerTest, StopAutoscrollOnResize) {
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
<!DOCTYPE html>
<style>
#scrollable {
width: 820px;
height: 620px;
}
</style>
<div id='scrollable'></div>
)HTML");
Compositor().BeginFrame();
AutoscrollController& controller = GetAutoscrollController();
EXPECT_FALSE(controller.IsAutoscrolling());
LocalFrame* frame = GetDocument().GetFrame();
controller.StartMiddleClickAutoscroll(frame, GetDocument().GetLayoutView(),
FloatPoint(), FloatPoint());
EXPECT_TRUE(controller.IsAutoscrolling());
// Confirm that it correctly stops autoscrolling when scrolling is no longer
// possible
WebView().MainFrameWidget()->Resize(WebSize(840, 640));
WebMouseEvent mouse_move_event(WebInputEvent::Type::kMouseMove,
WebInputEvent::kNoModifiers,
base::TimeTicks::Now());
frame->GetEventHandler().HandleMouseMoveEvent(
mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
EXPECT_FALSE(controller.IsAutoscrolling());
// Confirm that autoscrolling doesn't restart when scrolling is available
// again
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
WebMouseEvent mouse_move_event2(WebInputEvent::Type::kMouseMove,
WebInputEvent::kNoModifiers,
base::TimeTicks::Now());
frame->GetEventHandler().HandleMouseMoveEvent(
mouse_move_event2, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
EXPECT_FALSE(controller.IsAutoscrolling());
// And finally confirm that autoscrolling can start again.
controller.StartMiddleClickAutoscroll(frame, GetDocument().GetLayoutView(),
FloatPoint(), FloatPoint());
EXPECT_TRUE(controller.IsAutoscrolling());
}
} // namespace blink