Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights | 3 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights |
| 4 * reserved. | 4 * reserved. |
| 5 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
| 6 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) | 6 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) |
| 7 * | 7 * |
| 8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
| 9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
| 10 * are met: | 10 * are met: |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 */ | 28 */ |
| 29 | 29 |
| 30 #include "core/page/AutoscrollController.h" | 30 #include "core/page/AutoscrollController.h" |
| 31 | 31 |
| 32 #include "core/frame/FrameView.h" | 32 #include "core/frame/FrameView.h" |
| 33 #include "core/frame/LocalFrame.h" | 33 #include "core/frame/LocalFrame.h" |
| 34 #include "core/html/HTMLFrameOwnerElement.h" | |
| 34 #include "core/input/EventHandler.h" | 35 #include "core/input/EventHandler.h" |
| 35 #include "core/layout/HitTestResult.h" | 36 #include "core/layout/HitTestResult.h" |
| 36 #include "core/layout/LayoutBox.h" | 37 #include "core/layout/LayoutBox.h" |
| 37 #include "core/layout/LayoutListBox.h" | 38 #include "core/layout/LayoutListBox.h" |
| 38 #include "core/page/ChromeClient.h" | 39 #include "core/page/ChromeClient.h" |
| 39 #include "core/page/Page.h" | 40 #include "core/page/Page.h" |
| 40 #include "wtf/CurrentTime.h" | 41 #include "wtf/CurrentTime.h" |
| 41 | 42 |
| 42 namespace blink { | 43 namespace blink { |
| 43 | 44 |
| 44 // Delay time in second for start autoscroll if pointer is in border edge of | 45 // Delay time in second for start autoscroll if pointer is in border edge of |
| 45 // scrollable element. | 46 // scrollable element. |
| 46 static double autoscrollDelay = 0.2; | 47 static double autoscrollDelay = 0.2; |
| 47 | 48 |
| 48 AutoscrollController* AutoscrollController::create(Page& page) { | 49 AutoscrollController* AutoscrollController::create(Page& page) { |
| 49 return new AutoscrollController(page); | 50 return new AutoscrollController(page); |
| 50 } | 51 } |
| 51 | 52 |
| 52 AutoscrollController::AutoscrollController(Page& page) | 53 AutoscrollController::AutoscrollController(Page& page) |
| 53 : m_page(&page), | 54 : m_page(&page), |
| 54 m_autoscrollLayoutObject(nullptr), | 55 m_autoscrollLayoutObject(nullptr), |
| 55 m_pressedLayoutObject(nullptr), | 56 m_pressedLayoutObject(nullptr), |
| 56 m_autoscrollType(NoAutoscroll), | 57 m_autoscrollType(NoAutoscroll), |
| 57 m_dragAndDropAutoscrollStartTime(0) {} | 58 m_dragAndDropAutoscrollStartTime(0), |
| 59 m_middleClickAutoscrolled(false) {} | |
| 58 | 60 |
| 59 DEFINE_TRACE(AutoscrollController) { | 61 DEFINE_TRACE(AutoscrollController) { |
| 60 visitor->trace(m_page); | 62 visitor->trace(m_page); |
| 61 } | 63 } |
| 62 | 64 |
| 63 bool AutoscrollController::autoscrollInProgress() const { | 65 bool AutoscrollController::autoscrollInProgress() const { |
| 64 return m_autoscrollType == AutoscrollForSelection; | 66 return m_autoscrollType == AutoscrollForSelection; |
| 65 } | 67 } |
| 66 | 68 |
| 67 bool AutoscrollController::autoscrollInProgress( | 69 bool AutoscrollController::autoscrollInProgress( |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 const IntPoint& lastKnownMousePosition) { | 229 const IntPoint& lastKnownMousePosition) { |
| 228 DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); | 230 DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); |
| 229 // We don't want to trigger the autoscroll or the middleClickAutoscroll if | 231 // We don't want to trigger the autoscroll or the middleClickAutoscroll if |
| 230 // it's already active. | 232 // it's already active. |
| 231 if (m_autoscrollType != NoAutoscroll) | 233 if (m_autoscrollType != NoAutoscroll) |
| 232 return; | 234 return; |
| 233 | 235 |
| 234 m_autoscrollType = AutoscrollForMiddleClick; | 236 m_autoscrollType = AutoscrollForMiddleClick; |
| 235 m_autoscrollLayoutObject = scrollable; | 237 m_autoscrollLayoutObject = scrollable; |
| 236 m_middleClickAutoscrollStartPos = lastKnownMousePosition; | 238 m_middleClickAutoscrollStartPos = lastKnownMousePosition; |
| 239 m_middleClickAutoscrolled = false; | |
| 237 | 240 |
| 238 UseCounter::count(m_page->mainFrame(), | 241 UseCounter::count(m_page->mainFrame(), |
| 239 UseCounter::MiddleClickAutoscrollStart); | 242 UseCounter::MiddleClickAutoscrollStart); |
| 240 startAutoscroll(); | 243 startAutoscroll(); |
| 241 } | 244 } |
| 242 | 245 |
| 246 static inline int adjustedScrollDelta(int beginningDelta) { | |
| 247 // This implemention matches Firefox's. | |
| 248 // http://mxr.mozilla.org/firefox/source/toolkit/content/widgets/browser.xml#8 56. | |
| 249 const int speedReducer = 12; | |
| 250 | |
| 251 int adjustedDelta = beginningDelta / speedReducer; | |
| 252 if (adjustedDelta > 1) { | |
| 253 adjustedDelta = static_cast<int>(adjustedDelta * | |
| 254 sqrt(static_cast<double>(adjustedDelta))) - | |
| 255 1; | |
| 256 } else if (adjustedDelta < -1) { | |
| 257 adjustedDelta = | |
| 258 static_cast<int>(adjustedDelta * | |
| 259 sqrt(static_cast<double>(-adjustedDelta))) + | |
| 260 1; | |
| 261 } | |
| 262 | |
| 263 return adjustedDelta; | |
| 264 } | |
| 265 | |
| 266 static inline IntSize adjustedScrollDelta(const IntSize& delta) { | |
| 267 return IntSize(adjustedScrollDelta(delta.width()), | |
| 268 adjustedScrollDelta(delta.height())); | |
| 269 } | |
| 270 | |
| 271 FloatSize AutoscrollController::calculateAutoscrollDelta() { | |
| 272 LocalFrame* frame = m_autoscrollLayoutObject->frame(); | |
| 273 if (!frame) | |
| 274 return FloatSize(); | |
| 275 | |
| 276 IntPoint lastKnownMousePosition = | |
| 277 frame->eventHandler().lastKnownMousePosition(); | |
| 278 | |
| 279 // We need to check if the last known mouse position is out of the window. | |
| 280 // When the mouse is out of the window, the position is incoherent | |
| 281 static IntPoint previousMousePosition; | |
| 282 if (lastKnownMousePosition.x() < 0 || lastKnownMousePosition.y() < 0) | |
| 283 lastKnownMousePosition = previousMousePosition; | |
| 284 else | |
| 285 previousMousePosition = lastKnownMousePosition; | |
| 286 | |
| 287 IntSize delta = lastKnownMousePosition - m_middleClickAutoscrollStartPos; | |
| 288 | |
| 289 // at the center we let the space for the icon. | |
| 290 if (abs(delta.width()) <= noMiddleClickAutoscrollRadius) | |
| 291 delta.setWidth(0); | |
| 292 if (abs(delta.height()) <= noMiddleClickAutoscrollRadius) | |
| 293 delta.setHeight(0); | |
| 294 return FloatSize(adjustedScrollDelta(delta)); | |
| 295 } | |
| 296 | |
| 243 void AutoscrollController::animate(double) { | 297 void AutoscrollController::animate(double) { |
| 244 if (!m_autoscrollLayoutObject || !m_autoscrollLayoutObject->frame()) { | 298 if (!m_autoscrollLayoutObject || !m_autoscrollLayoutObject->frame()) { |
| 245 stopAutoscroll(); | 299 stopAutoscroll(); |
| 246 return; | 300 return; |
| 247 } | 301 } |
| 248 | 302 |
| 249 EventHandler& eventHandler = | 303 EventHandler& eventHandler = |
| 250 m_autoscrollLayoutObject->frame()->eventHandler(); | 304 m_autoscrollLayoutObject->frame()->eventHandler(); |
| 251 IntSize offset = m_autoscrollLayoutObject->calculateAutoscrollDirection( | 305 IntSize offset = m_autoscrollLayoutObject->calculateAutoscrollDirection( |
| 252 eventHandler.lastKnownMousePosition()); | 306 eventHandler.lastKnownMousePosition()); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 272 case AutoscrollForMiddleClickCanStop: | 326 case AutoscrollForMiddleClickCanStop: |
| 273 case AutoscrollForMiddleClick: | 327 case AutoscrollForMiddleClick: |
| 274 DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); | 328 DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); |
| 275 if (!middleClickAutoscrollInProgress()) { | 329 if (!middleClickAutoscrollInProgress()) { |
| 276 stopAutoscroll(); | 330 stopAutoscroll(); |
| 277 return; | 331 return; |
| 278 } | 332 } |
| 279 if (FrameView* view = m_autoscrollLayoutObject->frame()->view()) | 333 if (FrameView* view = m_autoscrollLayoutObject->frame()->view()) |
| 280 updateMiddleClickAutoscrollState(view, | 334 updateMiddleClickAutoscrollState(view, |
| 281 eventHandler.lastKnownMousePosition()); | 335 eventHandler.lastKnownMousePosition()); |
| 282 m_autoscrollLayoutObject->middleClickAutoscroll( | 336 FloatSize delta = calculateAutoscrollDelta(); |
| 283 m_middleClickAutoscrollStartPos); | 337 if (delta.isZero()) |
| 338 break; | |
| 339 ScrollResult result = | |
| 340 m_autoscrollLayoutObject->scroll(ScrollByPixel, delta); | |
| 341 LayoutObject* layoutObject = m_autoscrollLayoutObject; | |
| 342 while (!m_middleClickAutoscrolled && !result.didScroll()) { | |
| 343 if (layoutObject->node() && layoutObject->node()->isDocumentNode()) { | |
| 344 Element* owner = toDocument(layoutObject->node())->localOwner(); | |
| 345 layoutObject = owner ? owner->layoutObject() : nullptr; | |
| 346 } else { | |
| 347 layoutObject = layoutObject->parent(); | |
| 348 } | |
| 349 if (!layoutObject) { | |
| 350 break; | |
| 351 } | |
| 352 if (layoutObject && layoutObject->isBox() && | |
| 353 toLayoutBox(layoutObject)->canBeScrolledAndHasScrollableArea()) | |
| 354 result = toLayoutBox(layoutObject)->scroll(ScrollByPixel, delta); | |
| 355 } | |
| 356 if (result.didScroll()) { | |
| 357 m_middleClickAutoscrolled = true; | |
|
bokan
2016/11/11 19:48:46
This variable would be more descriptive as m_didLa
| |
| 358 m_autoscrollLayoutObject = toLayoutBox(layoutObject); | |
| 359 } | |
| 284 break; | 360 break; |
| 285 } | 361 } |
| 286 if (m_autoscrollType != NoAutoscroll && m_autoscrollLayoutObject) | 362 if (m_autoscrollType != NoAutoscroll && m_autoscrollLayoutObject) |
| 287 m_page->chromeClient().scheduleAnimation( | 363 m_page->chromeClient().scheduleAnimation( |
| 288 m_autoscrollLayoutObject->frame()->view()); | 364 m_autoscrollLayoutObject->frame()->view()); |
| 289 } | 365 } |
| 290 | 366 |
| 291 void AutoscrollController::startAutoscroll() { | 367 void AutoscrollController::startAutoscroll() { |
| 292 m_page->chromeClient().scheduleAnimation( | 368 m_page->chromeClient().scheduleAnimation( |
| 293 m_autoscrollLayoutObject->frame()->view()); | 369 m_autoscrollLayoutObject->frame()->view()); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 } else if (east) { | 405 } else if (east) { |
| 330 view->setCursor(eastPanningCursor()); | 406 view->setCursor(eastPanningCursor()); |
| 331 } else if (west) { | 407 } else if (west) { |
| 332 view->setCursor(westPanningCursor()); | 408 view->setCursor(westPanningCursor()); |
| 333 } else { | 409 } else { |
| 334 view->setCursor(middlePanningCursor()); | 410 view->setCursor(middlePanningCursor()); |
| 335 } | 411 } |
| 336 } | 412 } |
| 337 | 413 |
| 338 } // namespace blink | 414 } // namespace blink |
| OLD | NEW |