Changeset 163975 in webkit


Ignore:
Timestamp:
Feb 12, 2014 12:40:17 PM (10 years ago)
Author:
Brent Fulgham
Message:

Wheel events don't latch to inner scrollable elements
https://bugs.webkit.org/show_bug.cgi?id=128225
<rdar://problem/12183688>

Reviewed by Simon Fraser

  • WebCore.exp.in: Add declarations for new scrolledToTop, scrolledToBottom, scrolledToLeft, and scrolledToRight.
  • page/EventHandler.cpp:

(WebCore::EventHandler::EventHandler):
(WebCore::EventHandler::clear):
(WebCore::findScrollableContainer): New helper function to locate first node
in enclosing region of document that is capable of handling mouse wheel events.
(WebCore::isAtMaxDominantScrollPosition): Predicate to check if the scrollable
area is at the limit we will hit based on scroll direction.
(WebCore::EventHandler::handleWheelEvent): Identify the case where we have hit
the end of a scroll, and treat that as a valid 'handled' case. If the scroll event
is just starting, treat end-of-scroll as unhandled so the parent element can
handle things.

  • page/EventHandler.h:
  • page/scrolling/ScrollingTree.cpp:

(WebCore::ScrollingTree::shouldHandleWheelEventSynchronously): Use new methods
on the PlatformWheelEvent class.
(WebCore::ScrollingTree::setOrClearLatchedNode): Ditto

  • platform/PlatformWheelEvent.h:

(WebCore::PlatformWheelEvent::shouldConsiderLatching): Moved implementation from ScrollingTree.
(WebCore::PlatformWheelEvent::shouldClearLatchedNode): Ditto

  • platform/ScrollableArea.cpp:

(WebCore::ScrollableArea::scrolledToTop): Added
(WebCore::ScrollableArea::scrolledToBottom):Added
(WebCore::ScrollableArea::scrolledToLeft): Added
(WebCore::ScrollableArea::scrolledToRight): Added

  • platform/ScrollableArea.h:
  • rendering/RenderListBox.cpp:

(WebCore::RenderListBox::scrolledToTop): Added
(WebCore::RenderListBox::scrolledToBottom): Added
(WebCore::RenderListBox::scrolledToLeft): Added
(WebCore::RenderListBox::scrolledToRight): Added

  • rendering/RenderListBox.h: Changed to public inheritance of ScrollableArea to

allow generic use of this type in scroll wheel logic.

Location:
trunk/Source/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r163974 r163975  
     12014-02-12  Brent Fulgham  <bfulgham@apple.com>
     2
     3        Wheel events don't latch to inner scrollable elements
     4        https://bugs.webkit.org/show_bug.cgi?id=128225
     5        <rdar://problem/12183688>
     6
     7        Reviewed by Simon Fraser
     8
     9        * WebCore.exp.in: Add declarations for new scrolledToTop, scrolledToBottom, scrolledToLeft, and scrolledToRight.
     10        * page/EventHandler.cpp:
     11        (WebCore::EventHandler::EventHandler):
     12        (WebCore::EventHandler::clear):
     13        (WebCore::findScrollableContainer): New helper function to locate first node
     14        in enclosing region of document that is capable of handling mouse wheel events.
     15        (WebCore::isAtMaxDominantScrollPosition): Predicate to check if the scrollable
     16        area is at the limit we will hit based on scroll direction.
     17        (WebCore::EventHandler::handleWheelEvent): Identify the case where we have hit
     18        the end of a scroll, and treat that as a valid 'handled' case. If the scroll event
     19        is just starting, treat end-of-scroll as unhandled so the parent element can
     20        handle things.
     21        * page/EventHandler.h:
     22        * page/scrolling/ScrollingTree.cpp:
     23        (WebCore::ScrollingTree::shouldHandleWheelEventSynchronously): Use new methods
     24        on the PlatformWheelEvent class.
     25        (WebCore::ScrollingTree::setOrClearLatchedNode): Ditto
     26        * platform/PlatformWheelEvent.h:
     27        (WebCore::PlatformWheelEvent::shouldConsiderLatching): Moved implementation from ScrollingTree.
     28        (WebCore::PlatformWheelEvent::shouldClearLatchedNode): Ditto
     29        * platform/ScrollableArea.cpp:
     30        (WebCore::ScrollableArea::scrolledToTop): Added
     31        (WebCore::ScrollableArea::scrolledToBottom):Added
     32        (WebCore::ScrollableArea::scrolledToLeft): Added
     33        (WebCore::ScrollableArea::scrolledToRight): Added
     34        * platform/ScrollableArea.h:
     35        * rendering/RenderListBox.cpp:
     36        (WebCore::RenderListBox::scrolledToTop): Added
     37        (WebCore::RenderListBox::scrolledToBottom): Added
     38        (WebCore::RenderListBox::scrolledToLeft): Added
     39        (WebCore::RenderListBox::scrolledToRight): Added
     40        * rendering/RenderListBox.h: Changed to public inheritance of ScrollableArea to
     41        allow generic use of this type in scroll wheel logic.
     42
    1432014-02-12  Brendan Long  <b.long@cablelabs.com>
    244
  • trunk/Source/WebCore/WebCore.exp.in

    r163920 r163975  
    397397__ZN7WebCore14ScrollableArea15didAddScrollbarEPNS_9ScrollbarENS_20ScrollbarOrientationE
    398398__ZN7WebCore14ScrollableArea16handleWheelEventERKNS_18PlatformWheelEventE
     399__ZNK7WebCore14ScrollableArea16scrolledToBottomEv
     400__ZNK7WebCore14ScrollableArea14scrolledToLeftEv
     401__ZNK7WebCore14ScrollableArea13scrolledToTopEv
     402__ZNK7WebCore14ScrollableArea15scrolledToRightEv
    399403__ZN7WebCore14ScrollableArea17willEndLiveResizeEv
    400404__ZN7WebCore14ScrollableArea19invalidateScrollbarEPNS_9ScrollbarERKNS_7IntRectE
  • trunk/Source/WebCore/page/EventHandler.cpp

    r163725 r163975  
    11/*
    2  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006-2014 Apple Inc. All rights reserved.
    33 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
    44 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
     
    7373#include "RenderFrameSet.h"
    7474#include "RenderLayer.h"
     75#include "RenderListBox.h"
    7576#include "RenderTextControlSingleLine.h"
    7677#include "RenderView.h"
     
    354355    , m_mouseDownView(nil)
    355356    , m_sendingEventToSubview(false)
     357    , m_startedGestureAtScrollLimit(false)
    356358#if !PLATFORM(IOS)
    357359    , m_activationEventNumber(-1)
     
    433435    m_capturingMouseEventsElement = nullptr;
    434436    m_latchedWheelEventElement = nullptr;
     437#if PLATFORM(COCOA)
     438    m_latchedScrollableContainer = nullptr;
     439#endif
    435440    m_previousWheelScrolledElement = nullptr;
    436441#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
     
    24432448#endif
    24442449
     2450#if !PLATFORM(MAC)
     2451void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent&, const HitTestResult&, Element*&, ContainerNode*&, ScrollableArea*&, bool&)
     2452{
     2453}
     2454
     2455void EventHandler::platformRecordWheelEvent(const PlatformWheelEvent& event)
     2456{
     2457    m_recentWheelEventDeltaTracker->recordWheelEventDelta(event);
     2458}
     2459
     2460bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& event, ContainerNode*, ScrollableArea*)
     2461{
     2462    // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
     2463    FrameView* view = m_frame.view();
     2464   
     2465    bool didHandleEvent = view ? view->wheelEvent(event) : false;
     2466    m_isHandlingWheelEvent = false;
     2467    return didHandleEvent;
     2468}
     2469#endif
     2470
    24452471bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
    24462472{
     
    24642490    document->renderView()->hitTest(request, result);
    24652491
    2466     bool useLatchedWheelEventElement = e.useLatchedEventElement();
    2467 
    24682492    Element* element = result.innerElement();
    24692493
    2470     bool isOverWidget;
    2471     if (useLatchedWheelEventElement) {
    2472         if (!m_latchedWheelEventElement) {
    2473             m_latchedWheelEventElement = element;
    2474             m_widgetIsLatched = result.isOverWidget();
    2475         } else
    2476             element = m_latchedWheelEventElement.get();
    2477 
    2478         isOverWidget = m_widgetIsLatched;
    2479     } else {
    2480         if (m_latchedWheelEventElement)
    2481             m_latchedWheelEventElement = nullptr;
    2482         if (m_previousWheelScrolledElement)
    2483             m_previousWheelScrolledElement = nullptr;
    2484 
    2485         isOverWidget = result.isOverWidget();
    2486     }
     2494    bool isOverWidget = result.isOverWidget();
     2495
     2496    ContainerNode* scrollableContainer = nullptr;
     2497    ScrollableArea* scrollableArea = nullptr;
     2498    platformPrepareForWheelEvents(e, result, element, scrollableContainer, scrollableArea, isOverWidget);
    24872499
    24882500    // FIXME: It should not be necessary to do this mutation here.
     
    24932505        event = event.copyTurningVerticalTicksIntoHorizontalTicks();
    24942506
    2495 #if PLATFORM(COCOA)
    2496     switch (event.phase()) {
    2497     case PlatformWheelEventPhaseBegan:
    2498         m_recentWheelEventDeltaTracker->beginTrackingDeltas();
    2499         break;
    2500     case PlatformWheelEventPhaseEnded:
    2501         m_recentWheelEventDeltaTracker->endTrackingDeltas();
    2502         break;
    2503     default:
    2504         break;
    2505     }
    2506 #endif
    2507 
    2508     m_recentWheelEventDeltaTracker->recordWheelEventDelta(event);
     2507    platformRecordWheelEvent(event);
    25092508
    25102509    if (element) {
     
    25262525    }
    25272526
    2528 
    2529     // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
    2530     view = m_frame.view();
    2531     bool didHandleEvent = view ? view->wheelEvent(event) : false;
    2532     m_isHandlingWheelEvent = false;
    2533     return didHandleEvent;
     2527    return platformCompleteWheelEvent(e, scrollableContainer, scrollableArea);
    25342528}
    25352529
  • trunk/Source/WebCore/page/EventHandler.h

    r163725 r163975  
    11/*
    2  * Copyright (C) 2006, 2007, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006-2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7070class AutoscrollController;
    7171class Clipboard;
     72class ContainerNode;
    7273class Document;
    7374class Element;
     
    9192class RenderLayer;
    9293class RenderWidget;
     94class ScrollableArea;
    9395class SVGElementInstance;
    9496class Scrollbar;
     
    197199    void defaultWheelEventHandler(Node*, WheelEvent*);
    198200    bool handlePasteGlobalSelection(const PlatformMouseEvent&);
     201
     202    void platformPrepareForWheelEvents(const PlatformWheelEvent& wheelEvent, const HitTestResult& result, Element*& wheelEventTarget, ContainerNode*& scrollableContainer, ScrollableArea*& scrollableArea, bool& isOverWidget);
     203    void platformRecordWheelEvent(const PlatformWheelEvent&);
     204    bool platformCompleteWheelEvent(const PlatformWheelEvent&, ContainerNode* scrollableContainer, ScrollableArea* scrollableArea);
    199205
    200206#if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS)
     
    521527#if PLATFORM(COCOA)
    522528    NSView *m_mouseDownView;
     529    RefPtr<ContainerNode> m_latchedScrollableContainer;
    523530    bool m_sendingEventToSubview;
     531    bool m_startedGestureAtScrollLimit;
    524532#if !PLATFORM(IOS)
    525533    int m_activationEventNumber;
  • trunk/Source/WebCore/page/mac/EventHandlerMac.mm

    r163406 r163975  
    11/*
    2  * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3939#include "FrameView.h"
    4040#include "KeyboardEvent.h"
     41#include "MainFrame.h"
    4142#include "MouseEventWithHitTestResults.h"
    4243#include "NotImplemented.h"
     
    4445#include "Pasteboard.h"
    4546#include "PlatformEventFactoryMac.h"
     47#include "RenderLayer.h"
     48#include "RenderListBox.h"
    4649#include "RenderWidget.h"
    4750#include "RuntimeApplicationChecks.h"
     51#include "ScrollableArea.h"
    4852#include "Scrollbar.h"
    4953#include "Settings.h"
     54#include "ShadowRoot.h"
    5055#include "WebCoreSystemInterface.h"
    5156#include <wtf/MainThread.h>
     
    735740}
    736741
    737 }
     742static ContainerNode* findEnclosingScrollableContainer(ContainerNode& node)
     743{
     744    // Find the first node with a valid scrollable area starting with the current
     745    // node and traversing its parents (or shadow hosts).
     746    for (ContainerNode* candidate = &node; candidate; candidate = candidate->parentOrShadowHostNode()) {
     747        RenderBox* box = candidate->renderBox();
     748        if (box && box->canBeScrolledAndHasScrollableArea())
     749            return candidate;
     750    }
     751   
     752    return nullptr;
     753}
     754
     755static bool scrolledToEdgeInDominantDirection(const ScrollableArea& area, DominantScrollGestureDirection direction, float deltaX, float deltaY)
     756{
     757    if (DominantScrollGestureDirection::Horizontal == direction && deltaX) {
     758        if (deltaX < 0)
     759            return area.scrolledToRight();
     760       
     761        return area.scrolledToLeft();
     762    }
     763   
     764    if (deltaY < 0)
     765        return area.scrolledToBottom();
     766   
     767    return area.scrolledToTop();
     768}
     769
     770void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent& wheelEvent, const HitTestResult& result, Element*& wheelEventTarget, ContainerNode*& scrollableContainer, ScrollableArea*& scrollableArea, bool& isOverWidget)
     771{
     772    FrameView* view = m_frame.view();
     773
     774    scrollableContainer = nullptr;
     775    scrollableArea = nullptr;
     776    if (!view || !view->frame().isMainFrame()) {
     777        scrollableContainer = wheelEventTarget;
     778        scrollableArea = view;
     779    } else {
     780        scrollableContainer = findEnclosingScrollableContainer(*wheelEventTarget);
     781        if (scrollableContainer) {
     782            if (RenderBox* box = scrollableContainer->renderBox()) {
     783                if (box->isListBox())
     784                    scrollableArea = toRenderListBox(box);
     785                else
     786                    scrollableArea = box->layer();
     787            }
     788        }
     789    }
     790   
     791    if (wheelEvent.shouldConsiderLatching()) {
     792        if (scrollableArea)
     793            m_startedGestureAtScrollLimit = scrolledToEdgeInDominantDirection(*scrollableArea, m_recentWheelEventDeltaTracker->dominantScrollGestureDirection(), wheelEvent.deltaX(), wheelEvent.deltaY());
     794        else
     795            m_startedGestureAtScrollLimit = false;
     796        m_latchedWheelEventElement = wheelEventTarget;
     797        m_latchedScrollableContainer = scrollableContainer;
     798        m_widgetIsLatched = result.isOverWidget();
     799        isOverWidget = m_widgetIsLatched;
     800        m_recentWheelEventDeltaTracker->beginTrackingDeltas();
     801    } else if (wheelEvent.shouldResetLatching()) {
     802        m_latchedWheelEventElement = nullptr;
     803        m_latchedScrollableContainer = nullptr;
     804        m_widgetIsLatched = false;
     805        m_previousWheelScrolledElement = nullptr;
     806        m_recentWheelEventDeltaTracker->endTrackingDeltas();
     807    }
     808   
     809    if (!wheelEvent.shouldResetLatching() && m_latchedWheelEventElement) {
     810        wheelEventTarget = m_latchedWheelEventElement.get();
     811        isOverWidget = m_widgetIsLatched;
     812    }
     813}
     814
     815void EventHandler::platformRecordWheelEvent(const PlatformWheelEvent& wheelEvent)
     816{
     817    switch (wheelEvent.phase()) {
     818        case PlatformWheelEventPhaseBegan:
     819            m_recentWheelEventDeltaTracker->beginTrackingDeltas();
     820            break;
     821        case PlatformWheelEventPhaseEnded:
     822            m_recentWheelEventDeltaTracker->endTrackingDeltas();
     823            break;
     824        default:
     825            break;
     826    }
     827
     828    m_recentWheelEventDeltaTracker->recordWheelEventDelta(wheelEvent);
     829}
     830
     831bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& wheelEvent, ContainerNode* scrollableContainer, ScrollableArea* scrollableArea)
     832{
     833    // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
     834    FrameView* view = m_frame.view();
     835
     836    if (wheelEvent.useLatchedEventElement() && m_latchedScrollableContainer) {
     837        if (!view || !view->frame().isMainFrame()) {
     838            bool didHandleWheelEvent = view && view->wheelEvent(wheelEvent);
     839            if (!didHandleWheelEvent && scrollableContainer == m_latchedScrollableContainer) {
     840                // If we are just starting a scroll event, and have nowhere left to scroll, allow
     841                // the enclosing frame to handle the scroll.
     842                didHandleWheelEvent = !m_startedGestureAtScrollLimit;
     843            }
     844            m_isHandlingWheelEvent = false;
     845            return didHandleWheelEvent;
     846        }
     847       
     848        if (scrollableArea && !m_startedGestureAtScrollLimit && scrollableContainer == m_latchedScrollableContainer) {
     849            m_isHandlingWheelEvent = false;
     850            return true;
     851        }
     852    }
     853   
     854    bool didHandleEvent = view ? view->wheelEvent(wheelEvent) : false;
     855    m_isHandlingWheelEvent = false;
     856    return didHandleEvent;
     857}
     858
     859}
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp

    r163516 r163975  
    5959}
    6060
    61 static bool shouldConsiderLatching(const PlatformWheelEvent& wheelEvent)
    62 {
    63     return wheelEvent.phase() == PlatformWheelEventPhaseBegan
    64         || wheelEvent.phase() == PlatformWheelEventPhaseMayBegin;
    65 }
    66 
    67 static bool eventShouldClearLatchedNode(const PlatformWheelEvent& wheelEvent)
    68 {
    69     if (wheelEvent.phase() == PlatformWheelEventPhaseCancelled)
    70         return true;
    71    
    72     if (wheelEvent.phase() == PlatformWheelEventPhaseNone && wheelEvent.momentumPhase() == PlatformWheelEventPhaseEnded)
    73         return true;
    74    
    75     return false;
    76 }
    77 
    7861bool ScrollingTree::shouldHandleWheelEventSynchronously(const PlatformWheelEvent& wheelEvent)
    7962{
     
    8467        return true;
    8568
    86     bool shouldSetLatch = shouldConsiderLatching(wheelEvent);
     69    bool shouldSetLatch = wheelEvent.shouldConsiderLatching();
    8770   
    8871    if (hasLatchedNode() && !shouldSetLatch)
     
    10487void ScrollingTree::setOrClearLatchedNode(const PlatformWheelEvent& wheelEvent, ScrollingNodeID nodeID)
    10588{
    106     if (shouldConsiderLatching(wheelEvent))
     89    if (wheelEvent.shouldConsiderLatching())
    10790        setLatchedNode(nodeID);
    108     else if (eventShouldClearLatchedNode(wheelEvent))
     91    else if (wheelEvent.shouldResetLatching())
    10992        clearLatchedNode();
    11093}
  • trunk/Source/WebCore/platform/PlatformWheelEvent.h

    r163657 r163975  
    168168                || m_momentumPhase == PlatformWheelEventPhaseBegan || m_momentumPhase == PlatformWheelEventPhaseChanged;
    169169        }
     170        bool shouldConsiderLatching() const
     171        {
     172            return m_phase == PlatformWheelEventPhaseBegan || m_phase == PlatformWheelEventPhaseMayBegin;
     173        }
     174        bool shouldResetLatching() const
     175        {
     176            if (m_phase == PlatformWheelEventPhaseCancelled || m_phase == PlatformWheelEventPhaseMayBegin)
     177                return true;
     178           
     179            if (m_phase == PlatformWheelEventPhaseNone && m_momentumPhase == PlatformWheelEventPhaseEnded)
     180                return true;
     181           
     182            return false;
     183        }
    170184#else
    171185        bool useLatchedEventElement() const { return false; }
  • trunk/Source/WebCore/platform/ScrollableArea.cpp

    r163079 r163975  
    11/*
    22 * Copyright (c) 2010, Google Inc. All rights reserved.
    3  * Copyright (C) 2008, 2011 Apple Inc. All Rights Reserved.
     3 * Copyright (C) 2008, 2011, 2014 Apple Inc. All Rights Reserved.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    423423}
    424424
     425bool ScrollableArea::scrolledToTop() const
     426{
     427    return scrollPosition().y() <= minimumScrollPosition().y();
     428}
     429
     430bool ScrollableArea::scrolledToBottom() const
     431{
     432    return scrollPosition().y() >= maximumScrollPosition().y();
     433}
     434
     435bool ScrollableArea::scrolledToLeft() const
     436{
     437    return scrollPosition().x() <= minimumScrollPosition().x();
     438}
     439
     440bool ScrollableArea::scrolledToRight() const
     441{
     442    return scrollPosition().x() >= maximumScrollPosition().x();
     443}
     444
    425445IntSize ScrollableArea::totalContentsSize() const
    426446{
  • trunk/Source/WebCore/platform/ScrollableArea.h

    r163079 r163975  
    11/*
    2  * Copyright (C) 2008, 2011 Apple Inc. All Rights Reserved.
     2 * Copyright (C) 2008, 2011, 2014 Apple Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    150150    virtual IntPoint minimumScrollPosition() const;
    151151    virtual IntPoint maximumScrollPosition() const;
     152    virtual bool scrolledToTop() const;
     153    virtual bool scrolledToBottom() const;
     154    virtual bool scrolledToLeft() const;
     155    virtual bool scrolledToRight() const;
    152156
    153157    enum VisibleContentRectIncludesScrollbars { ExcludeScrollbars, IncludeScrollbars };
  • trunk/Source/WebCore/rendering/RenderListBox.cpp

    r163560 r163975  
    11/*
    2  * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008, 2011, 2014 Apple Inc. All rights reserved.
    33 *               2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
    44 *
     
    832832}
    833833
     834bool RenderListBox::scrolledToTop() const
     835{
     836    Scrollbar* vbar = verticalScrollbar();
     837    if (!vbar)
     838        return true;
     839   
     840    return vbar->value() <= 0;
     841}
     842
     843bool RenderListBox::scrolledToBottom() const
     844{
     845    Scrollbar* vbar = verticalScrollbar();
     846    if (!vbar)
     847        return true;
     848
     849    return vbar->value() >= vbar->maximum();
     850}
     851
     852bool RenderListBox::scrolledToLeft() const
     853{
     854    // We do not scroll horizontally in a select element, so always report
     855    // that we are at the full extent of the scroll.
     856    return true;
     857}
     858
     859bool RenderListBox::scrolledToRight() const
     860{
     861    // We do not scroll horizontally in a select element, so always report
     862    // that we are at the full extent of the scroll.
     863    return true;
     864}
     865   
    834866} // namespace WebCore
  • trunk/Source/WebCore/rendering/RenderListBox.h

    r163560 r163975  
    22 * This file is part of the select element renderer in WebCore.
    33 *
    4  * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
     4 * Copyright (C) 2006, 2007, 2009, 2014 Apple Inc. All rights reserved.
    55 *
    66 * Redistribution and use in source and binary forms, with or without
     
    3939class HTMLSelectElement;
    4040
    41 class RenderListBox final : public RenderBlockFlow, private ScrollableArea {
     41class RenderListBox final : public RenderBlockFlow, public ScrollableArea {
    4242public:
    4343    RenderListBox(HTMLSelectElement&, PassRef<RenderStyle>);
     
    5959
    6060    int size() const;
     61
     62    virtual bool scrolledToTop() const override;
     63    virtual bool scrolledToBottom() const override;
     64    virtual bool scrolledToLeft() const override;
     65    virtual bool scrolledToRight() const override;
    6166
    6267private:
Note: See TracChangeset for help on using the changeset viewer.