Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: third_party/WebKit/Source/core/input/ScrollManager.cpp

Issue 2010133003: Add ScrollManager class (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/input/ScrollManager.h"
6
7 #include "core/dom/DOMNodeIds.h"
8 #include "core/events/GestureEvent.h"
9 #include "core/frame/FrameHost.h"
10 #include "core/frame/FrameView.h"
11 #include "core/frame/TopControls.h"
12 #include "core/input/EventHandler.h"
13 #include "core/layout/LayoutPart.h"
14 #include "core/loader/DocumentLoader.h"
15 #include "core/page/AutoscrollController.h"
16 #include "core/page/Page.h"
17 #include "core/page/scrolling/OverscrollController.h"
18 #include "core/page/scrolling/RootScroller.h"
19 #include "core/page/scrolling/ScrollState.h"
20 #include "core/paint/PaintLayer.h"
21 #include "platform/PlatformGestureEvent.h"
22
23
24 namespace blink {
25
26 namespace {
27
28 // TODO(bokan): This method can go away once all scrolls happen through the
29 // scroll customization path.
30 void computeScrollChainForSingleNode(Node& node, std::deque<int>& scrollChain)
31 {
32 scrollChain.clear();
33
34 DCHECK(node.layoutObject());
35 Element* element = toElement(&node);
36
37 scrollChain.push_front(DOMNodeIds::idForNode(element));
38 }
39
40 void recomputeScrollChain(const LocalFrame& frame, const Node& startNode,
41 std::deque<int>& scrollChain)
42 {
43 scrollChain.clear();
44
45 DCHECK(startNode.layoutObject());
46 LayoutBox* curBox = startNode.layoutObject()->enclosingBox();
47
48 // Scrolling propagates along the containing block chain.
49 while (curBox && !curBox->isLayoutView()) {
50 Node* curNode = curBox->node();
51 // FIXME: this should reject more elements, as part of crbug.com/410974.
52 if (curNode && curNode->isElementNode()) {
53 Element* curElement = toElement(curNode);
54 if (curElement == frame.document()->scrollingElement())
55 break;
56 scrollChain.push_front(DOMNodeIds::idForNode(curElement));
57 }
58 curBox = curBox->containingBlock();
59 }
60 // TODO(tdresser): this should sometimes be excluded, as part of crbug.com/4 10974.
61 // We need to ensure that the scrollingElement is always part of
62 // the scroll chain. In quirks mode, when the scrollingElement is
63 // the body, some elements may use the documentElement as their
64 // containingBlock, so we ensure the scrollingElement is added
65 // here.
66 scrollChain.push_front(DOMNodeIds::idForNode(frame.document()->scrollingElem ent()));
67 }
68
69 } // namespace
70
71 ScrollManager::ScrollManager(LocalFrame* frame)
72 : m_frame(frame)
73 {
74 clear();
75 }
76
77 ScrollManager::~ScrollManager()
78 {
79 }
80
81 void ScrollManager::clear()
82 {
83 m_lastGestureScrollOverWidget = false;
84 m_scrollbarHandlingScrollGesture = nullptr;
85 m_resizeScrollableArea = nullptr;
86 m_offsetFromResizeCorner = LayoutSize();
87 clearGestureScrollState();
88 }
89
90 void ScrollManager::clearGestureScrollState()
91 {
92 m_scrollGestureHandlingNode = nullptr;
93 m_previousGestureScrolledNode = nullptr;
94 m_deltaConsumedForScrollSequence = false;
95 m_currentScrollChain.clear();
96
97 if (FrameHost* host = frameHost()) {
98 bool resetX = true;
99 bool resetY = true;
100 host->overscrollController().resetAccumulated(resetX, resetY);
101 }
102 }
103
104 void ScrollManager::stopAutoscroll()
105 {
106 if (AutoscrollController* controller = autoscrollController())
107 controller->stopAutoscroll();
108 }
109
110 bool ScrollManager::panScrollInProgress() const
111 {
112 return autoscrollController() && autoscrollController()->panScrollInProgress ();
113 }
114
115 AutoscrollController* ScrollManager::autoscrollController() const
116 {
117 if (Page* page = m_frame->page())
118 return &page->autoscrollController();
119 return nullptr;
120 }
121
122 ScrollResult ScrollManager::physicalScroll(ScrollGranularity granularity,
123 const FloatSize& delta, const FloatPoint& position,
124 const FloatSize& velocity, Node* startNode, Node** stopNode, bool* consumed)
125 {
126 if (consumed)
127 *consumed = false;
128 if (delta.isZero())
129 return ScrollResult();
130
131 Node* node = startNode;
132 DCHECK(node && node->layoutObject());
133
134 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets();
135
136 ScrollResult result;
137
138 LayoutBox* curBox = node->layoutObject()->enclosingBox();
139 while (curBox) {
140 // If we're at the stopNode, we should try to scroll it but we shouldn't
141 // chain past it.
142 bool shouldStopChaining =
143 stopNode && *stopNode && curBox->node() == *stopNode;
144 bool wasRootScroller = false;
145
146 result = scrollBox(
147 curBox,
148 granularity,
149 delta,
150 position,
151 velocity,
152 &wasRootScroller);
153
154 if (result.didScroll() && stopNode)
155 *stopNode = curBox->node();
156
157 if (result.didScroll() || shouldStopChaining) {
158 setFrameWasScrolledByUser();
159 if (consumed)
160 *consumed = true;
161 return result;
162 }
163 if (wasRootScroller) {
164 // Don't try to chain past the root scroller, even if there's
165 // eligible ancestors.
166 break;
167 }
168
169 curBox = curBox->containingBlock();
170 }
171
172 return result;
173 }
174
175 bool ScrollManager::logicalScroll(ScrollDirection direction, ScrollGranularity g ranularity, Node* startNode, Node* mousePressNode)
176 {
177 Node* node = startNode;
178
179 if (!node)
180 node = m_frame->document()->focusedElement();
181
182 if (!node)
183 node = mousePressNode;
184
185 if ((!node || !node->layoutObject()) && m_frame->view() && !m_frame->view()- >layoutViewItem().isNull())
186 node = m_frame->view()->layoutViewItem().node();
187
188 if (!node)
189 return false;
190
191 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets();
192
193 LayoutBox* curBox = node->layoutObject()->enclosingBox();
194 while (curBox) {
195 ScrollDirectionPhysical physicalDirection = toPhysicalDirection(
196 direction, curBox->isHorizontalWritingMode(), curBox->style()->isFli ppedBlocksWritingMode());
197
198 ScrollResult result = curBox->scroll(granularity, toScrollDelta(physical Direction, 1));
199
200 if (result.didScroll()) {
201 setFrameWasScrolledByUser();
202 return true;
203 }
204
205 curBox = curBox->containingBlock();
206 }
207
208 return false;
209 }
210
211 ScrollResult ScrollManager::scrollBox(LayoutBox* box,
212 ScrollGranularity granularity, const FloatSize& delta,
213 const FloatPoint& position, const FloatSize& velocity,
214 bool* wasRootScroller)
215 {
216 DCHECK(box);
217 Node* node = box->node();
218
219 // If there's no ApplyScroll callback on the element, scroll as usuall in
220 // the non-scroll-customization case.
221 if (!node || !node->isElementNode() || !toElement(node)->getApplyScroll()) {
222 *wasRootScroller = false;
223 return box->scroll(granularity, delta);
224 }
225
226 // Viewport actions should only happen when scrolling an element in the
227 // main frame.
228 DCHECK(m_frame->isMainFrame());
229
230 // If there is an ApplyScroll callback, its because we placed one on the
231 // root scroller to control top controls and overscroll. Invoke a scroll
232 // using parts of the scroll customization framework on just this element.
233 computeScrollChainForSingleNode(*node, m_currentScrollChain);
234
235 OwnPtr<ScrollStateData> scrollStateData = adoptPtr(new ScrollStateData());
236 scrollStateData->delta_x = delta.width();
237 scrollStateData->delta_y = delta.height();
238 scrollStateData->position_x = position.x();
239 scrollStateData->position_y = position.y();
240 // TODO(bokan): delta_granularity is meant to be the number of pixels per
241 // unit of delta but we can't determine that until we get to the area we'll
242 // scroll. This is a hack, we stuff the enum into the double value for
243 // now.
244 scrollStateData->delta_granularity = static_cast<double>(granularity);
245 scrollStateData->velocity_x = velocity.width();
246 scrollStateData->velocity_y = velocity.height();
247 scrollStateData->should_propagate = false;
248 scrollStateData->is_in_inertial_phase = false;
249 scrollStateData->from_user_input = true;
250 scrollStateData->delta_consumed_for_scroll_sequence = false;
251 ScrollState* scrollState =
252 ScrollState::create(std::move(scrollStateData));
253
254 customizedScroll(*node, *scrollState);
255
256 ScrollResult result(
257 scrollState->deltaX() != delta.width(),
258 scrollState->deltaY() != delta.height(),
259 scrollState->deltaX(),
260 scrollState->deltaY());
261
262 *wasRootScroller = true;
263 m_currentScrollChain.clear();
264
265 return result;
266 }
267
268 void ScrollManager::setFrameWasScrolledByUser()
269 {
270 if (DocumentLoader* documentLoader = m_frame->loader().documentLoader())
271 documentLoader->initialScrollState().wasScrolledByUser = true;
272 }
273
274 void ScrollManager::customizedScroll(const Node& startNode, ScrollState& scrollS tate)
275 {
276 if (scrollState.fullyConsumed())
277 return;
278
279 if (scrollState.deltaX() || scrollState.deltaY())
280 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets();
281
282 if (m_currentScrollChain.empty())
283 recomputeScrollChain(*m_frame, startNode, m_currentScrollChain);
284 scrollState.setScrollChain(m_currentScrollChain);
285
286 scrollState.distributeToScrollChainDescendant();
287 }
288
289 WebInputEventResult ScrollManager::handleGestureScrollBegin(const PlatformGestur eEvent& gestureEvent)
290 {
291 Document* document = m_frame->document();
292 if (document->layoutViewItem().isNull())
293 return WebInputEventResult::NotHandled;
294
295 FrameView* view = m_frame->view();
296 if (!view)
297 return WebInputEventResult::NotHandled;
298
299 // If there's no layoutObject on the node, send the event to the nearest anc estor with a layoutObject.
300 // Needed for <option> and <optgroup> elements so we can touch scroll <selec t>s
301 while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->layoutOb ject())
302 m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShado wHostNode();
303
304 if (!m_scrollGestureHandlingNode) {
305 if (RuntimeEnabledFeatures::scrollCustomizationEnabled())
306 m_scrollGestureHandlingNode = m_frame->document()->documentElement() ;
307 else
308 return WebInputEventResult::NotHandled;
309 }
310 DCHECK(m_scrollGestureHandlingNode);
311
312 passScrollGestureEventToWidget(gestureEvent, m_scrollGestureHandlingNode->la youtObject());
313 if (RuntimeEnabledFeatures::scrollCustomizationEnabled()) {
314 m_currentScrollChain.clear();
315 OwnPtr<ScrollStateData> scrollStateData = adoptPtr(new ScrollStateData() );
316 scrollStateData->position_x = gestureEvent.position().x();
317 scrollStateData->position_y = gestureEvent.position().y();
318 scrollStateData->is_beginning = true;
319 scrollStateData->from_user_input = true;
320 scrollStateData->delta_consumed_for_scroll_sequence = m_deltaConsumedFor ScrollSequence;
321 ScrollState* scrollState = ScrollState::create(std::move(scrollStateData ));
322 customizedScroll(*m_scrollGestureHandlingNode.get(), *scrollState);
323 } else {
324 if (m_frame->isMainFrame())
325 m_frame->host()->topControls().scrollBegin();
326 }
327 return WebInputEventResult::HandledSystem;
328 }
329
330 WebInputEventResult ScrollManager::handleGestureScrollUpdate(const PlatformGestu reEvent& gestureEvent)
331 {
332 DCHECK_EQ(gestureEvent.type(), PlatformEvent::GestureScrollUpdate);
333
334 // Negate the deltas since the gesture event stores finger movement and
335 // scrolling occurs in the direction opposite the finger's movement
336 // direction. e.g. Finger moving up has negative event delta but causes the
337 // page to scroll down causing positive scroll delta.
338 FloatSize delta(-gestureEvent.deltaX(), -gestureEvent.deltaY());
339 FloatSize velocity(-gestureEvent.velocityX(), -gestureEvent.velocityY());
340 if (delta.isZero())
341 return WebInputEventResult::NotHandled;
342
343 ScrollGranularity granularity = gestureEvent.deltaUnits();
344 Node* node = m_scrollGestureHandlingNode.get();
345
346 // Scroll customization is only available for touch.
347 bool handleScrollCustomization = RuntimeEnabledFeatures::scrollCustomization Enabled() && gestureEvent.source() == PlatformGestureSourceTouchscreen;
348 if (node) {
349 LayoutObject* layoutObject = node->layoutObject();
350 if (!layoutObject)
351 return WebInputEventResult::NotHandled;
352
353 // Try to send the event to the correct view.
354 WebInputEventResult result = passScrollGestureEventToWidget(gestureEvent , layoutObject);
355 if (result != WebInputEventResult::NotHandled) {
356 if (gestureEvent.preventPropagation()
357 && !RuntimeEnabledFeatures::scrollCustomizationEnabled()) {
358 // This is an optimization which doesn't apply with
359 // scroll customization enabled.
360 m_previousGestureScrolledNode = m_scrollGestureHandlingNode;
361 }
362 // FIXME: we should allow simultaneous scrolling of nested
363 // iframes along perpendicular axes. See crbug.com/466991.
364 m_deltaConsumedForScrollSequence = true;
365 return result;
366 }
367
368 if (handleScrollCustomization) {
369 OwnPtr<ScrollStateData> scrollStateData = adoptPtr(new ScrollStateDa ta());
370 scrollStateData->delta_x = delta.width();
371 scrollStateData->delta_y = delta.height();
372 scrollStateData->delta_granularity = ScrollByPrecisePixel;
373 scrollStateData->velocity_x = velocity.width();
374 scrollStateData->velocity_y = velocity.height();
375 scrollStateData->should_propagate = !gestureEvent.preventPropagation ();
376 scrollStateData->is_in_inertial_phase = gestureEvent.inertialPhase() == ScrollInertialPhaseMomentum;
377 scrollStateData->from_user_input = true;
378 scrollStateData->delta_consumed_for_scroll_sequence = m_deltaConsume dForScrollSequence;
379 ScrollState* scrollState = ScrollState::create(std::move(scrollState Data));
380 if (m_previousGestureScrolledNode) {
381 // The ScrollState needs to know what the current
382 // native scrolling element is, so that for an
383 // inertial scroll that shouldn't propagate, only the
384 // currently scrolling element responds.
385 DCHECK(m_previousGestureScrolledNode->isElementNode());
386 scrollState->setCurrentNativeScrollingElement(toElement(m_previo usGestureScrolledNode.get()));
387 }
388 customizedScroll(*node, *scrollState);
389 m_previousGestureScrolledNode = scrollState->currentNativeScrollingE lement();
390 m_deltaConsumedForScrollSequence = scrollState->deltaConsumedForScro llSequence();
391 if (scrollState->deltaX() != delta.width()
392 || scrollState->deltaY() != delta.height()) {
393 setFrameWasScrolledByUser();
394 return WebInputEventResult::HandledSystem;
395 }
396 } else {
397 Node* stopNode = nullptr;
398 if (gestureEvent.preventPropagation())
399 stopNode = m_previousGestureScrolledNode.get();
400
401 bool consumed = false;
402 ScrollResult result = physicalScroll(
403 granularity,
404 delta,
405 FloatPoint(gestureEvent.position()),
406 velocity,
407 node,
408 &stopNode,
409 &consumed);
410
411 if (gestureEvent.preventPropagation())
412 m_previousGestureScrolledNode = stopNode;
413
414 if ((!stopNode || !isRootScroller(*stopNode)) && frameHost()) {
415 frameHost()->overscrollController().resetAccumulated(
416 result.didScrollX, result.didScrollY);
417 }
418
419 if (consumed)
420 return WebInputEventResult::HandledSystem;
421 }
422 }
423
424 return WebInputEventResult::NotHandled;
425 }
426
427 WebInputEventResult ScrollManager::handleGestureScrollEnd(const PlatformGestureE vent& gestureEvent)
428 {
429 Node* node = m_scrollGestureHandlingNode;
430
431 if (node) {
432 passScrollGestureEventToWidget(gestureEvent, node->layoutObject());
433 if (RuntimeEnabledFeatures::scrollCustomizationEnabled()) {
434 OwnPtr<ScrollStateData> scrollStateData = adoptPtr(new ScrollStateDa ta());
435 scrollStateData->is_ending = true;
436 scrollStateData->is_in_inertial_phase = gestureEvent.inertialPhase() == ScrollInertialPhaseMomentum;
437 scrollStateData->from_user_input = true;
438 scrollStateData->is_direct_manipulation = true;
439 scrollStateData->delta_consumed_for_scroll_sequence = m_deltaConsume dForScrollSequence;
440 ScrollState* scrollState = ScrollState::create(std::move(scrollState Data));
441 customizedScroll(*node, *scrollState);
442 }
443 }
444
445 clearGestureScrollState();
446 return WebInputEventResult::NotHandled;
447 }
448
449 FrameHost* ScrollManager::frameHost() const
450 {
451 if (!m_frame->page())
452 return nullptr;
453
454 return &m_frame->page()->frameHost();
455 }
456
457 WebInputEventResult ScrollManager::passScrollGestureEventToWidget(const Platform GestureEvent& gestureEvent, LayoutObject* layoutObject)
458 {
459 DCHECK(gestureEvent.isScrollEvent());
460
461 if (!m_lastGestureScrollOverWidget || !layoutObject || !layoutObject->isLayo utPart())
462 return WebInputEventResult::NotHandled;
463
464 Widget* widget = toLayoutPart(layoutObject)->widget();
465
466 if (!widget || !widget->isFrameView())
467 return WebInputEventResult::NotHandled;
468
469 return toFrameView(widget)->frame().eventHandler().handleGestureScrollEvent( gestureEvent);
470 }
471
472 bool ScrollManager::isRootScroller(const Node& node) const
473 {
474 // The root scroller is the one Element on the page designated to perform
475 // "viewport actions" like top controls movement and overscroll glow.
476 if (!frameHost() || !frameHost()->rootScroller())
477 return false;
478
479 return frameHost()->rootScroller()->get() == &node;
480 }
481
482
483 WebInputEventResult ScrollManager::handleGestureScrollEvent(const PlatformGestur eEvent& gestureEvent)
484 {
485 Node* eventTarget = nullptr;
486 Scrollbar* scrollbar = nullptr;
487 if (gestureEvent.type() != PlatformEvent::GestureScrollBegin) {
488 scrollbar = m_scrollbarHandlingScrollGesture.get();
489 eventTarget = m_scrollGestureHandlingNode.get();
490 }
491
492 if (!eventTarget) {
493 Document* document = m_frame->document();
494 if (document->layoutViewItem().isNull())
495 return WebInputEventResult::NotHandled;
496
497 FrameView* view = m_frame->view();
498 LayoutPoint viewPoint = view->rootFrameToContents(gestureEvent.position( ));
499 HitTestRequest request(HitTestRequest::ReadOnly);
500 HitTestResult result(request, viewPoint);
501 document->layoutViewItem().hitTest(result);
502
503 eventTarget = result.innerNode();
504
505 m_lastGestureScrollOverWidget = result.isOverWidget();
506 m_scrollGestureHandlingNode = eventTarget;
507 m_previousGestureScrolledNode = nullptr;
508
509 if (!scrollbar)
510 scrollbar = result.scrollbar();
511 }
512
513 if (scrollbar) {
514 bool shouldUpdateCapture = false;
515 if (scrollbar->gestureEvent(gestureEvent, &shouldUpdateCapture)) {
516 if (shouldUpdateCapture)
517 m_scrollbarHandlingScrollGesture = scrollbar;
518 return WebInputEventResult::HandledSuppressed;
519 }
520 m_scrollbarHandlingScrollGesture = nullptr;
521 }
522
523 if (eventTarget) {
524 if (handleScrollGestureOnResizer(eventTarget, gestureEvent))
525 return WebInputEventResult::HandledSuppressed;
526
527 GestureEvent* gestureDomEvent = GestureEvent::create(eventTarget->docume nt().domWindow(), gestureEvent);
528 if (gestureDomEvent) {
529 DispatchEventResult gestureDomEventResult = eventTarget->dispatchEve nt(gestureDomEvent);
530 if (gestureDomEventResult != DispatchEventResult::NotCanceled) {
531 DCHECK(gestureDomEventResult != DispatchEventResult::CanceledByE ventHandler);
532 return EventHandler::toWebInputEventResult(gestureDomEventResult );
533 }
534 }
535 }
536
537 switch (gestureEvent.type()) {
538 case PlatformEvent::GestureScrollBegin:
539 return handleGestureScrollBegin(gestureEvent);
540 case PlatformEvent::GestureScrollUpdate:
541 return handleGestureScrollUpdate(gestureEvent);
542 case PlatformEvent::GestureScrollEnd:
543 return handleGestureScrollEnd(gestureEvent);
544 case PlatformEvent::GestureFlingStart:
545 case PlatformEvent::GesturePinchBegin:
546 case PlatformEvent::GesturePinchEnd:
547 case PlatformEvent::GesturePinchUpdate:
548 return WebInputEventResult::NotHandled;
549 default:
550 NOTREACHED();
551 return WebInputEventResult::NotHandled;
552 }
553 }
554
555 bool ScrollManager::isScrollbarHandlingGestures() const
556 {
557 return m_scrollbarHandlingScrollGesture.get();
558 }
559
560 bool ScrollManager::handleScrollGestureOnResizer(Node* eventTarget, const Platfo rmGestureEvent& gestureEvent)
561 {
562 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) {
563 PaintLayer* layer = eventTarget->layoutObject() ? eventTarget->layoutObj ect()->enclosingLayer() : nullptr;
564 IntPoint p = m_frame->view()->rootFrameToContents(gestureEvent.position( ));
565 if (layer && layer->getScrollableArea() && layer->getScrollableArea()->i sPointInResizeControl(p, ResizerForTouch)) {
566 m_resizeScrollableArea = layer->getScrollableArea();
567 m_resizeScrollableArea->setInResizeMode(true);
568 m_offsetFromResizeCorner = LayoutSize(m_resizeScrollableArea->offset FromResizeCorner(p));
569 return true;
570 }
571 } else if (gestureEvent.type() == PlatformEvent::GestureScrollUpdate) {
572 if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) {
573 m_resizeScrollableArea->resize(gestureEvent, m_offsetFromResizeCorne r);
574 return true;
575 }
576 } else if (gestureEvent.type() == PlatformEvent::GestureScrollEnd) {
577 if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) {
578 m_resizeScrollableArea->setInResizeMode(false);
579 m_resizeScrollableArea = nullptr;
580 return false;
581 }
582 }
583
584 return false;
585 }
586
587 bool ScrollManager::inResizeMode() const
588 {
589 return m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode();
590 }
591
592 void ScrollManager::resize(const PlatformEvent& evt)
593 {
594 m_resizeScrollableArea->resize(evt, m_offsetFromResizeCorner);
595 }
596
597 void ScrollManager::clearResizeScrollableArea(bool shouldNotBeNull)
598 {
599 if (shouldNotBeNull)
600 DCHECK(m_resizeScrollableArea);
601
602 if (m_resizeScrollableArea)
603 m_resizeScrollableArea->setInResizeMode(false);
604 m_resizeScrollableArea = nullptr;
605 }
606
607 void ScrollManager::setResizeScrollableArea(PaintLayer* layer, IntPoint p)
608 {
609 m_resizeScrollableArea = layer->getScrollableArea();
610 m_resizeScrollableArea->setInResizeMode(true);
611 m_offsetFromResizeCorner = LayoutSize(m_resizeScrollableArea->offsetFromResi zeCorner(p));
612 }
613
614 bool ScrollManager::canHandleGestureEvent(const GestureEventWithHitTestResults& targetedEvent)
615 {
616 Scrollbar* scrollbar = targetedEvent.hitTestResult().scrollbar();
617 const PlatformGestureEvent& gestureEvent = targetedEvent.event();
dtapuska 2016/05/27 14:12:23 do you need to put this on the stack? Should be ab
Navid Zolghadr 2016/05/30 20:15:47 Yup. You are right.
618
619 if (scrollbar) {
620 bool shouldUpdateCapture = false;
621 if (scrollbar->gestureEvent(gestureEvent, &shouldUpdateCapture)) {
622 if (shouldUpdateCapture)
623 m_scrollbarHandlingScrollGesture = scrollbar;
624 return true;
625 }
626 }
627 return false;
628 }
629
630 DEFINE_TRACE(ScrollManager)
631 {
632 visitor->trace(m_frame);
633 visitor->trace(m_scrollGestureHandlingNode);
634 visitor->trace(m_previousGestureScrolledNode);
635 visitor->trace(m_scrollbarHandlingScrollGesture);
636 visitor->trace(m_resizeScrollableArea);
637 }
638
639 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698