OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010, Google Inc. All rights reserved. | 2 * Copyright (c) 2010, Google Inc. All rights reserved. |
3 * Copyright (C) 2008, 2011 Apple Inc. All Rights Reserved. | 3 * Copyright (C) 2008, 2011 Apple Inc. All Rights Reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 14 matching lines...) Expand all Loading... |
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
32 #include "platform/scroll/ScrollableArea.h" | 32 #include "platform/scroll/ScrollableArea.h" |
33 | 33 |
34 #include "platform/HostWindow.h" | 34 #include "platform/HostWindow.h" |
35 #include "platform/geometry/DoubleRect.h" | |
36 #include "platform/geometry/FloatPoint.h" | |
37 #include "platform/geometry/LayoutRect.h" | |
38 #include "platform/graphics/GraphicsLayer.h" | 35 #include "platform/graphics/GraphicsLayer.h" |
39 #include "platform/scroll/MainThreadScrollingReason.h" | 36 #include "platform/scroll/MainThreadScrollingReason.h" |
40 #include "platform/scroll/ProgrammaticScrollAnimator.h" | 37 #include "platform/scroll/ProgrammaticScrollAnimator.h" |
41 #include "platform/scroll/ScrollbarTheme.h" | 38 #include "platform/scroll/ScrollbarTheme.h" |
42 | 39 |
43 #include "platform/tracing/TraceEvent.h" | 40 #include "platform/tracing/TraceEvent.h" |
44 | 41 |
45 static const int kPixelsPerLineStep = 40; | 42 static const int kPixelsPerLineStep = 40; |
46 static const float kMinFractionToStepWhenPaging = 0.875f; | 43 static const float kMinFractionToStepWhenPaging = 0.875f; |
47 | 44 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 case ScrollByPixel: | 137 case ScrollByPixel: |
141 case ScrollByPrecisePixel: | 138 case ScrollByPrecisePixel: |
142 return pixelStep(orientation); | 139 return pixelStep(orientation); |
143 default: | 140 default: |
144 ASSERT_NOT_REACHED(); | 141 ASSERT_NOT_REACHED(); |
145 return 0.0f; | 142 return 0.0f; |
146 } | 143 } |
147 } | 144 } |
148 | 145 |
149 ScrollResult ScrollableArea::userScroll(ScrollGranularity granularity, | 146 ScrollResult ScrollableArea::userScroll(ScrollGranularity granularity, |
150 const FloatSize& delta) { | 147 const ScrollOffset& delta) { |
151 float stepX = scrollStep(granularity, HorizontalScrollbar); | 148 float stepX = scrollStep(granularity, HorizontalScrollbar); |
152 float stepY = scrollStep(granularity, VerticalScrollbar); | 149 float stepY = scrollStep(granularity, VerticalScrollbar); |
153 | 150 |
154 FloatSize pixelDelta(delta); | 151 ScrollOffset pixelDelta(delta); |
155 pixelDelta.scale(stepX, stepY); | 152 pixelDelta.scale(stepX, stepY); |
156 | 153 |
157 FloatSize scrollableAxisDelta( | 154 ScrollOffset scrollableAxisDelta( |
158 userInputScrollable(HorizontalScrollbar) ? pixelDelta.width() : 0, | 155 userInputScrollable(HorizontalScrollbar) ? pixelDelta.width() : 0, |
159 userInputScrollable(VerticalScrollbar) ? pixelDelta.height() : 0); | 156 userInputScrollable(VerticalScrollbar) ? pixelDelta.height() : 0); |
160 | 157 |
161 if (scrollableAxisDelta.isZero()) { | 158 if (scrollableAxisDelta.isZero()) { |
162 return ScrollResult(false, false, pixelDelta.width(), pixelDelta.height()); | 159 return ScrollResult(false, false, pixelDelta.width(), pixelDelta.height()); |
163 } | 160 } |
164 | 161 |
165 cancelProgrammaticScrollAnimation(); | 162 cancelProgrammaticScrollAnimation(); |
166 | 163 |
167 ScrollResult result = scrollAnimator().userScroll(granularity, pixelDelta); | 164 ScrollResult result = scrollAnimator().userScroll(granularity, pixelDelta); |
168 | 165 |
169 // Delta that wasn't scrolled because the axis is !userInputScrollable | 166 // Delta that wasn't scrolled because the axis is !userInputScrollable |
170 // should count as unusedScrollDelta. | 167 // should count as unusedScrollDelta. |
171 FloatSize unscrollableAxisDelta = pixelDelta - scrollableAxisDelta; | 168 ScrollOffset unscrollableAxisDelta = pixelDelta - scrollableAxisDelta; |
172 result.unusedScrollDeltaX += unscrollableAxisDelta.width(); | 169 result.unusedScrollDeltaX += unscrollableAxisDelta.width(); |
173 result.unusedScrollDeltaY += unscrollableAxisDelta.height(); | 170 result.unusedScrollDeltaY += unscrollableAxisDelta.height(); |
174 | 171 |
175 return result; | 172 return result; |
176 } | 173 } |
177 | 174 |
178 void ScrollableArea::setScrollPosition(const DoublePoint& position, | 175 void ScrollableArea::setScrollOffset(const ScrollOffset& offset, |
179 ScrollType scrollType, | 176 ScrollType scrollType, |
180 ScrollBehavior behavior) { | 177 ScrollBehavior behavior) { |
181 DoublePoint clampedPosition = clampScrollPosition(position); | 178 ScrollOffset clampedOffset = clampScrollOffset(offset); |
182 if (shouldUseIntegerScrollOffset()) | 179 if (clampedOffset == scrollOffset()) |
183 clampedPosition = flooredIntPoint(clampedPosition); | |
184 if (clampedPosition == scrollPositionDouble()) | |
185 return; | 180 return; |
186 | 181 |
187 if (behavior == ScrollBehaviorAuto) | 182 if (behavior == ScrollBehaviorAuto) |
188 behavior = scrollBehaviorStyle(); | 183 behavior = scrollBehaviorStyle(); |
189 | 184 |
190 switch (scrollType) { | 185 switch (scrollType) { |
191 case CompositorScroll: | 186 case CompositorScroll: |
192 scrollPositionChanged(clampedPosition, scrollType); | 187 scrollOffsetChanged(clampedOffset, scrollType); |
193 break; | 188 break; |
194 case AnchoringScroll: | 189 case AnchoringScroll: |
195 scrollAnimator().adjustAnimationAndSetScrollPosition(clampedPosition, | 190 scrollAnimator().adjustAnimationAndSetScrollOffset(clampedOffset, |
196 scrollType); | 191 scrollType); |
197 break; | 192 break; |
198 case ProgrammaticScroll: | 193 case ProgrammaticScroll: |
199 programmaticScrollHelper(clampedPosition, behavior); | 194 programmaticScrollHelper(clampedOffset, behavior); |
200 break; | 195 break; |
201 case UserScroll: | 196 case UserScroll: |
202 userScrollHelper(clampedPosition, behavior); | 197 userScrollHelper(clampedOffset, behavior); |
203 break; | 198 break; |
204 default: | 199 default: |
205 ASSERT_NOT_REACHED(); | 200 ASSERT_NOT_REACHED(); |
206 } | 201 } |
207 } | 202 } |
208 | 203 |
209 void ScrollableArea::scrollBy(const DoubleSize& delta, | 204 void ScrollableArea::scrollBy(const ScrollOffset& delta, |
210 ScrollType type, | 205 ScrollType type, |
211 ScrollBehavior behavior) { | 206 ScrollBehavior behavior) { |
212 setScrollPosition(scrollPositionDouble() + delta, type, behavior); | 207 setScrollOffset(scrollOffset() + delta, type, behavior); |
213 } | 208 } |
214 | 209 |
215 void ScrollableArea::setScrollPositionSingleAxis( | 210 void ScrollableArea::setScrollOffsetSingleAxis(ScrollbarOrientation orientation, |
216 ScrollbarOrientation orientation, | 211 float offset, |
217 double position, | 212 ScrollType scrollType, |
218 ScrollType scrollType, | 213 ScrollBehavior behavior) { |
219 ScrollBehavior behavior) { | 214 ScrollOffset newOffset; |
220 DoublePoint newPosition; | |
221 if (orientation == HorizontalScrollbar) | 215 if (orientation == HorizontalScrollbar) |
222 newPosition = DoublePoint(position, scrollAnimator().currentPosition().y()); | 216 newOffset = ScrollOffset(offset, scrollAnimator().currentOffset().height()); |
223 else | 217 else |
224 newPosition = DoublePoint(scrollAnimator().currentPosition().x(), position); | 218 newOffset = ScrollOffset(scrollAnimator().currentOffset().width(), offset); |
225 | 219 |
226 // TODO(bokan): Note, this doesn't use the derived class versions since this | 220 // TODO(bokan): Note, this doesn't use the derived class versions since this |
227 // method is currently used exclusively by code that adjusts the position by | 221 // method is currently used exclusively by code that adjusts the position by |
228 // the scroll origin and the derived class versions differ on whether they | 222 // the scroll origin and the derived class versions differ on whether they |
229 // take that into account or not. | 223 // take that into account or not. |
230 ScrollableArea::setScrollPosition(newPosition, scrollType, behavior); | 224 ScrollableArea::setScrollOffset(newOffset, scrollType, behavior); |
231 } | 225 } |
232 | 226 |
233 void ScrollableArea::programmaticScrollHelper(const DoublePoint& position, | 227 void ScrollableArea::programmaticScrollHelper(const ScrollOffset& offset, |
234 ScrollBehavior scrollBehavior) { | 228 ScrollBehavior scrollBehavior) { |
235 cancelScrollAnimation(); | 229 cancelScrollAnimation(); |
236 | 230 |
237 if (scrollBehavior == ScrollBehaviorSmooth) | 231 if (scrollBehavior == ScrollBehaviorSmooth) |
238 programmaticScrollAnimator().animateToOffset(toFloatPoint(position)); | 232 programmaticScrollAnimator().animateToOffset(offset); |
239 else | 233 else |
240 programmaticScrollAnimator().scrollToOffsetWithoutAnimation( | 234 programmaticScrollAnimator().scrollToOffsetWithoutAnimation(offset); |
241 toFloatPoint(position)); | |
242 } | 235 } |
243 | 236 |
244 void ScrollableArea::userScrollHelper(const DoublePoint& position, | 237 void ScrollableArea::userScrollHelper(const ScrollOffset& offset, |
245 ScrollBehavior scrollBehavior) { | 238 ScrollBehavior scrollBehavior) { |
246 cancelProgrammaticScrollAnimation(); | 239 cancelProgrammaticScrollAnimation(); |
247 | 240 |
248 double x = userInputScrollable(HorizontalScrollbar) | 241 float x = userInputScrollable(HorizontalScrollbar) |
249 ? position.x() | 242 ? offset.width() |
250 : scrollAnimator().currentPosition().x(); | 243 : scrollAnimator().currentOffset().width(); |
251 double y = userInputScrollable(VerticalScrollbar) | 244 float y = userInputScrollable(VerticalScrollbar) |
252 ? position.y() | 245 ? offset.height() |
253 : scrollAnimator().currentPosition().y(); | 246 : scrollAnimator().currentOffset().height(); |
254 | 247 |
255 // Smooth user scrolls (keyboard, wheel clicks) are handled via the userScroll | 248 // Smooth user scrolls (keyboard, wheel clicks) are handled via the userScroll |
256 // method. | 249 // method. |
257 // TODO(bokan): The userScroll method should probably be modified to call this | 250 // TODO(bokan): The userScroll method should probably be modified to call this |
258 // method and ScrollAnimatorBase to have a simpler | 251 // method and ScrollAnimatorBase to have a simpler |
259 // animateToOffset method like the ProgrammaticScrollAnimator. | 252 // animateToOffset method like the ProgrammaticScrollAnimator. |
260 ASSERT(scrollBehavior == ScrollBehaviorInstant); | 253 ASSERT(scrollBehavior == ScrollBehaviorInstant); |
261 scrollAnimator().scrollToOffsetWithoutAnimation(FloatPoint(x, y)); | 254 scrollAnimator().scrollToOffsetWithoutAnimation(ScrollOffset(x, y)); |
262 } | 255 } |
263 | 256 |
264 LayoutRect ScrollableArea::scrollIntoView(const LayoutRect& rectInContent, | 257 LayoutRect ScrollableArea::scrollIntoView(const LayoutRect& rectInContent, |
265 const ScrollAlignment& alignX, | 258 const ScrollAlignment& alignX, |
266 const ScrollAlignment& alignY, | 259 const ScrollAlignment& alignY, |
267 ScrollType) { | 260 ScrollType) { |
268 // TODO(bokan): This should really be implemented here but ScrollAlignment is | 261 // TODO(bokan): This should really be implemented here but ScrollAlignment is |
269 // in Core which is a dependency violation. | 262 // in Core which is a dependency violation. |
270 ASSERT_NOT_REACHED(); | 263 ASSERT_NOT_REACHED(); |
271 return LayoutRect(); | 264 return LayoutRect(); |
272 } | 265 } |
273 | 266 |
274 void ScrollableArea::scrollPositionChanged(const DoublePoint& position, | 267 void ScrollableArea::scrollOffsetChanged(const ScrollOffset& offset, |
275 ScrollType scrollType) { | 268 ScrollType scrollType) { |
276 TRACE_EVENT0("blink", "ScrollableArea::scrollPositionChanged"); | 269 TRACE_EVENT0("blink", "ScrollableArea::scrollOffsetChanged"); |
277 | 270 |
278 DoublePoint oldPosition = scrollPositionDouble(); | 271 ScrollOffset oldOffset = scrollOffset(); |
279 DoublePoint truncatedPosition = | 272 ScrollOffset truncatedOffset = shouldUseIntegerScrollOffset() |
280 shouldUseIntegerScrollOffset() ? flooredIntPoint(position) : position; | 273 ? ScrollOffset(flooredIntSize(offset)) |
| 274 : offset; |
281 | 275 |
282 // Tell the derived class to scroll its contents. | 276 // Tell the derived class to scroll its contents. |
283 setScrollOffset(truncatedPosition, scrollType); | 277 updateScrollOffset(truncatedOffset, scrollType); |
284 | 278 |
285 // Tell the scrollbars to update their thumb postions. | 279 // Tell the scrollbars to update their thumb postions. |
286 // If the scrollbar does not have its own layer, it must always be | 280 // If the scrollbar does not have its own layer, it must always be |
287 // invalidated to reflect the new thumb position, even if the theme did not | 281 // invalidated to reflect the new thumb offset, even if the theme did not |
288 // invalidate any individual part. | 282 // invalidate any individual part. |
289 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) | 283 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) |
290 horizontalScrollbar->offsetDidChange(); | 284 horizontalScrollbar->offsetDidChange(); |
291 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) | 285 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) |
292 verticalScrollbar->offsetDidChange(); | 286 verticalScrollbar->offsetDidChange(); |
293 | 287 |
294 if (scrollPositionDouble() != oldPosition) { | 288 if (scrollOffset() != oldOffset) |
295 // FIXME: Pass in DoubleSize. crbug.com/414283. | 289 scrollAnimator().notifyContentAreaScrolled(scrollOffset() - oldOffset); |
296 scrollAnimator().notifyContentAreaScrolled( | |
297 toFloatSize(scrollPositionDouble() - oldPosition)); | |
298 } | |
299 | 290 |
300 scrollAnimator().setCurrentPosition(toFloatPoint(position)); | 291 scrollAnimator().setCurrentOffset(offset); |
301 } | 292 } |
302 | 293 |
303 bool ScrollableArea::scrollBehaviorFromString(const String& behaviorString, | 294 bool ScrollableArea::scrollBehaviorFromString(const String& behaviorString, |
304 ScrollBehavior& behavior) { | 295 ScrollBehavior& behavior) { |
305 if (behaviorString == "auto") | 296 if (behaviorString == "auto") |
306 behavior = ScrollBehaviorAuto; | 297 behavior = ScrollBehaviorAuto; |
307 else if (behaviorString == "instant") | 298 else if (behaviorString == "instant") |
308 behavior = ScrollBehaviorInstant; | 299 behavior = ScrollBehaviorInstant; |
309 else if (behaviorString == "smooth") | 300 else if (behaviorString == "smooth") |
310 behavior = ScrollBehaviorSmooth; | 301 behavior = ScrollBehaviorSmooth; |
311 else | 302 else |
312 return false; | 303 return false; |
313 | 304 |
314 return true; | 305 return true; |
315 } | 306 } |
316 | 307 |
317 // NOTE: Only called from Internals for testing. | 308 // NOTE: Only called from Internals for testing. |
318 void ScrollableArea::setScrollOffsetFromInternals(const IntPoint& offset) { | 309 void ScrollableArea::updateScrollOffsetFromInternals(const IntSize& offset) { |
319 scrollPositionChanged(DoublePoint(offset), ProgrammaticScroll); | 310 scrollOffsetChanged(ScrollOffset(offset), ProgrammaticScroll); |
320 } | 311 } |
321 | 312 |
322 void ScrollableArea::contentAreaWillPaint() const { | 313 void ScrollableArea::contentAreaWillPaint() const { |
323 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) | 314 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) |
324 scrollAnimator->contentAreaWillPaint(); | 315 scrollAnimator->contentAreaWillPaint(); |
325 } | 316 } |
326 | 317 |
327 void ScrollableArea::mouseEnteredContentArea() const { | 318 void ScrollableArea::mouseEnteredContentArea() const { |
328 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) | 319 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) |
329 scrollAnimator->mouseEnteredContentArea(); | 320 scrollAnimator->mouseEnteredContentArea(); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 // scheduled on the compositor. | 521 // scheduled on the compositor. |
531 // TODO(ymalik): We have a non-transient "main thread scrolling reason" | 522 // TODO(ymalik): We have a non-transient "main thread scrolling reason" |
532 // that doesn't actually cause shouldScrollOnMainThread() to be true. | 523 // that doesn't actually cause shouldScrollOnMainThread() to be true. |
533 // This is confusing and should be cleaned up. | 524 // This is confusing and should be cleaned up. |
534 return !!(reasons & | 525 return !!(reasons & |
535 ~MainThreadScrollingReason::kHandlingScrollFromMainThread); | 526 ~MainThreadScrollingReason::kHandlingScrollFromMainThread); |
536 } | 527 } |
537 return true; | 528 return true; |
538 } | 529 } |
539 | 530 |
540 DoubleRect ScrollableArea::visibleContentRectDouble( | |
541 IncludeScrollbarsInRect scrollbarInclusion) const { | |
542 return visibleContentRect(scrollbarInclusion); | |
543 } | |
544 | |
545 IntRect ScrollableArea::visibleContentRect( | 531 IntRect ScrollableArea::visibleContentRect( |
546 IncludeScrollbarsInRect scrollbarInclusion) const { | 532 IncludeScrollbarsInRect scrollbarInclusion) const { |
547 int scrollbarWidth = | 533 int scrollbarWidth = |
548 scrollbarInclusion == IncludeScrollbars ? verticalScrollbarWidth() : 0; | 534 scrollbarInclusion == IncludeScrollbars ? verticalScrollbarWidth() : 0; |
549 int scrollbarHeight = | 535 int scrollbarHeight = |
550 scrollbarInclusion == IncludeScrollbars ? horizontalScrollbarHeight() : 0; | 536 scrollbarInclusion == IncludeScrollbars ? horizontalScrollbarHeight() : 0; |
551 | 537 |
552 return IntRect(scrollPosition().x(), scrollPosition().y(), | 538 return enclosingIntRect( |
553 std::max(0, visibleWidth() + scrollbarWidth), | 539 IntRect(scrollOffset().width(), scrollOffset().height(), |
554 std::max(0, visibleHeight() + scrollbarHeight)); | 540 std::max(0, visibleWidth() + scrollbarWidth), |
| 541 std::max(0, visibleHeight() + scrollbarHeight))); |
555 } | 542 } |
556 | 543 |
557 IntPoint ScrollableArea::clampScrollPosition( | 544 IntSize ScrollableArea::clampScrollOffset(const IntSize& scrollOffset) const { |
558 const IntPoint& scrollPosition) const { | 545 return scrollOffset.shrunkTo(maximumScrollOffsetInt()) |
559 return scrollPosition.shrunkTo(maximumScrollPosition()) | 546 .expandedTo(minimumScrollOffsetInt()); |
560 .expandedTo(minimumScrollPosition()); | |
561 } | 547 } |
562 | 548 |
563 DoublePoint ScrollableArea::clampScrollPosition( | 549 ScrollOffset ScrollableArea::clampScrollOffset( |
564 const DoublePoint& scrollPosition) const { | 550 const ScrollOffset& scrollOffset) const { |
565 return scrollPosition.shrunkTo(maximumScrollPositionDouble()) | 551 return scrollOffset.shrunkTo(maximumScrollOffset()) |
566 .expandedTo(minimumScrollPositionDouble()); | 552 .expandedTo(minimumScrollOffset()); |
567 } | 553 } |
568 | 554 |
569 int ScrollableArea::lineStep(ScrollbarOrientation) const { | 555 int ScrollableArea::lineStep(ScrollbarOrientation) const { |
570 return pixelsPerLineStep(getHostWindow()); | 556 return pixelsPerLineStep(getHostWindow()); |
571 } | 557 } |
572 | 558 |
573 int ScrollableArea::pageStep(ScrollbarOrientation orientation) const { | 559 int ScrollableArea::pageStep(ScrollbarOrientation orientation) const { |
574 IntRect visibleRect = visibleContentRect(IncludeScrollbars); | 560 IntRect visibleRect = visibleContentRect(IncludeScrollbars); |
575 int length = (orientation == HorizontalScrollbar) ? visibleRect.width() | 561 int length = (orientation == HorizontalScrollbar) ? visibleRect.width() |
576 : visibleRect.height(); | 562 : visibleRect.height(); |
(...skipping 27 matching lines...) Expand all Loading... |
604 return IntSize(std::max(0, size.width() - verticalScrollbarWidth()), | 590 return IntSize(std::max(0, size.width() - verticalScrollbarWidth()), |
605 std::max(0, size.height() - horizontalScrollbarHeight())); | 591 std::max(0, size.height() - horizontalScrollbarHeight())); |
606 } | 592 } |
607 | 593 |
608 DEFINE_TRACE(ScrollableArea) { | 594 DEFINE_TRACE(ScrollableArea) { |
609 visitor->trace(m_scrollAnimator); | 595 visitor->trace(m_scrollAnimator); |
610 visitor->trace(m_programmaticScrollAnimator); | 596 visitor->trace(m_programmaticScrollAnimator); |
611 } | 597 } |
612 | 598 |
613 } // namespace blink | 599 } // namespace blink |
OLD | NEW |