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

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

Powered by Google App Engine
This is Rietveld 408576698