summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc
blob: d27ef082bc37b7a6c74e0dd27c3e8f79475ae918 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright 2016 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/scroll/scrollbar_theme_overlay.h"

#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_test_suite.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"

namespace blink {

using testing::NiceMock;
using testing::Return;

class ScrollbarThemeOverlayTest : public testing::Test {};

TEST_F(ScrollbarThemeOverlayTest, PaintInvalidation) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform;

  NiceMock<MockScrollableArea>* mock_scrollable_area =
      MakeGarbageCollected<NiceMock<MockScrollableArea>>(
          ScrollOffset(100, 100));
  ScrollbarThemeOverlay theme(14, 0);

  Scrollbar* vertical_scrollbar = Scrollbar::CreateForTesting(
      mock_scrollable_area, kVerticalScrollbar, kRegularScrollbar, &theme);
  Scrollbar* horizontal_scrollbar = Scrollbar::CreateForTesting(
      mock_scrollable_area, kHorizontalScrollbar, kRegularScrollbar, &theme);
  ON_CALL(*mock_scrollable_area, VerticalScrollbar())
      .WillByDefault(Return(vertical_scrollbar));
  ON_CALL(*mock_scrollable_area, HorizontalScrollbar())
      .WillByDefault(Return(horizontal_scrollbar));

  IntRect vertical_rect(1010, 0, 14, 768);
  IntRect horizontal_rect(0, 754, 1024, 14);
  vertical_scrollbar->SetFrameRect(vertical_rect);
  horizontal_scrollbar->SetFrameRect(horizontal_rect);

  ASSERT_EQ(vertical_scrollbar, mock_scrollable_area->VerticalScrollbar());
  ASSERT_EQ(horizontal_scrollbar, mock_scrollable_area->HorizontalScrollbar());

  vertical_scrollbar->ClearTrackNeedsRepaint();
  vertical_scrollbar->ClearThumbNeedsRepaint();
  horizontal_scrollbar->ClearTrackNeedsRepaint();
  horizontal_scrollbar->ClearThumbNeedsRepaint();
  mock_scrollable_area->ClearNeedsPaintInvalidationForScrollControls();

  ASSERT_FALSE(vertical_scrollbar->ThumbNeedsRepaint());
  ASSERT_FALSE(vertical_scrollbar->TrackNeedsRepaint());
  ASSERT_FALSE(mock_scrollable_area->VerticalScrollbarNeedsPaintInvalidation());
  ASSERT_FALSE(horizontal_scrollbar->ThumbNeedsRepaint());
  ASSERT_FALSE(horizontal_scrollbar->TrackNeedsRepaint());
  ASSERT_FALSE(
      mock_scrollable_area->HorizontalScrollbarNeedsPaintInvalidation());

  // Changing the scroll offset shouldn't invalid the thumb nor track, but it
  // should cause a "general" invalidation for non-composited scrollbars.
  // Ensure the horizontal scrollbar is unaffected.
  mock_scrollable_area->UpdateScrollOffset(ScrollOffset(0, 5),
                                           mojom::blink::ScrollType::kUser);
  vertical_scrollbar->OffsetDidChange(mojom::blink::ScrollType::kUser);
  horizontal_scrollbar->OffsetDidChange(mojom::blink::ScrollType::kUser);
  EXPECT_FALSE(vertical_scrollbar->ThumbNeedsRepaint());
  EXPECT_FALSE(vertical_scrollbar->TrackNeedsRepaint());
  EXPECT_TRUE(mock_scrollable_area->VerticalScrollbarNeedsPaintInvalidation());
  EXPECT_FALSE(horizontal_scrollbar->ThumbNeedsRepaint());
  EXPECT_FALSE(horizontal_scrollbar->TrackNeedsRepaint());
  EXPECT_FALSE(
      mock_scrollable_area->HorizontalScrollbarNeedsPaintInvalidation());

  // Try the horizontal scrollbar.
  mock_scrollable_area->ClearNeedsPaintInvalidationForScrollControls();
  mock_scrollable_area->UpdateScrollOffset(ScrollOffset(5, 5),
                                           mojom::blink::ScrollType::kUser);
  horizontal_scrollbar->OffsetDidChange(mojom::blink::ScrollType::kUser);
  vertical_scrollbar->OffsetDidChange(mojom::blink::ScrollType::kUser);
  EXPECT_FALSE(vertical_scrollbar->ThumbNeedsRepaint());
  EXPECT_FALSE(vertical_scrollbar->TrackNeedsRepaint());
  EXPECT_FALSE(mock_scrollable_area->VerticalScrollbarNeedsPaintInvalidation());
  EXPECT_FALSE(horizontal_scrollbar->ThumbNeedsRepaint());
  EXPECT_FALSE(horizontal_scrollbar->TrackNeedsRepaint());
  EXPECT_TRUE(
      mock_scrollable_area->HorizontalScrollbarNeedsPaintInvalidation());

  mock_scrollable_area->ClearNeedsPaintInvalidationForScrollControls();

  // Move the mouse over the vertical scrollbar's thumb. Ensure the thumb is
  // invalidated as its state is changed to hover.
  vertical_scrollbar->SetHoveredPart(kThumbPart);
  EXPECT_TRUE(vertical_scrollbar->ThumbNeedsRepaint());
  EXPECT_TRUE(mock_scrollable_area->VerticalScrollbarNeedsPaintInvalidation());

  vertical_scrollbar->ClearThumbNeedsRepaint();
  mock_scrollable_area->ClearNeedsPaintInvalidationForScrollControls();

  // Pressing down should also cause an invalidation.
  vertical_scrollbar->SetPressedPart(kThumbPart, WebInputEvent::kMouseDown);
  EXPECT_TRUE(vertical_scrollbar->ThumbNeedsRepaint());
  EXPECT_TRUE(mock_scrollable_area->VerticalScrollbarNeedsPaintInvalidation());

  vertical_scrollbar->ClearThumbNeedsRepaint();
  mock_scrollable_area->ClearNeedsPaintInvalidationForScrollControls();

  // Release should cause invalidation.
  vertical_scrollbar->SetPressedPart(kNoPart, WebInputEvent::kMouseDown);
  EXPECT_TRUE(vertical_scrollbar->ThumbNeedsRepaint());
  EXPECT_TRUE(mock_scrollable_area->VerticalScrollbarNeedsPaintInvalidation());

  vertical_scrollbar->ClearThumbNeedsRepaint();
  mock_scrollable_area->ClearNeedsPaintInvalidationForScrollControls();

  // Move off should cause invalidation
  vertical_scrollbar->SetHoveredPart(kNoPart);
  EXPECT_TRUE(vertical_scrollbar->ThumbNeedsRepaint());
  EXPECT_TRUE(mock_scrollable_area->VerticalScrollbarNeedsPaintInvalidation());

  vertical_scrollbar->ClearThumbNeedsRepaint();
  mock_scrollable_area->ClearNeedsPaintInvalidationForScrollControls();

  // Hiding the scrollbar should invalidate the layer (SetNeedsDisplay) but not
  // trigger repaint of the thumb resouce, since the compositor will give the
  // entire layer opacity 0.
  EXPECT_CALL(*mock_scrollable_area, ScrollbarsHiddenIfOverlay())
      .WillOnce(Return(true));
  vertical_scrollbar->SetEnabled(false);
  EXPECT_FALSE(vertical_scrollbar->ThumbNeedsRepaint());
  EXPECT_TRUE(mock_scrollable_area->VerticalScrollbarNeedsPaintInvalidation());

  mock_scrollable_area->ClearNeedsPaintInvalidationForScrollControls();

  // Showing the scrollbar needs to repaint the thumb resource, since it may
  // have been repainted in the disabled state while hidden (e.g. from
  // SetProportion on bounds changes).
  EXPECT_CALL(*mock_scrollable_area, ScrollbarsHiddenIfOverlay())
      .WillOnce(Return(false));
  vertical_scrollbar->SetEnabled(true);
  EXPECT_TRUE(vertical_scrollbar->ThumbNeedsRepaint());
  EXPECT_TRUE(mock_scrollable_area->VerticalScrollbarNeedsPaintInvalidation());

  ThreadState::Current()->CollectAllGarbageForTesting();
}

}  // namespace blink