Changeset 55436 in webkit


Ignore:
Timestamp:
Mar 2, 2010 3:33:38 PM (14 years ago)
Author:
mrowe@apple.com
Message:

WebCore: Add the capability to create and dispatch a WheelEvent in JavaScript.
Ensure the event's default handler is triggered in the same way as it is
during a PlatformWheelEvent.

Patch by Andy Estes <aestes@apple.com> on 2010-03-02
Reviewed by Maciej Stachowiak.

https://bugs.webkit.org/show_bug.cgi?id=35566

Test: fast/events/wheelevent-in-scrolling-div.html

  • dom/Node.cpp: Ensure that the default behavior (scrolling) occurs for

wheel events originating both from the platform and from
JavaScript/ObjC.
(WebCore::Node::dispatchWheelEvent): Instantiate new WheelEvent with
the graunularity of the PlatformWheelEvent.
(WebCore::Node::defaultEventHandler): Add support for mousewheel events.

  • dom/WheelEvent.cpp: Add three new member variables: m_deltaX, m_deltaY

and m_granularity. m_deltaX and m_deltaY differ from m_wheelDeltaX and
m_wheelDeltaY, which are the number of wheel ticks multiplied by 120 for
IE compatibility.
(WebCore::WheelEvent::WheelEvent): Initialize new member variables.
(WebCore::WheelEvent::initWheelEvent): Same.
(WebCore::WheelEvent::initWebKitWheelEvent): Same.

  • dom/WheelEvent.h: See WheelEvent.cpp.

(WebCore::WheelEvent::): Add Granularity enum (Pixel, Line, Page).
(WebCore::WheelEvent::create): Add new arguments.
(WebCore::WheelEvent::deltaX): Amount of scroll in x direction.
(WebCore::WheelEvent::deltaY): Amount of scroll in y direction.
(WebCore::WheelEvent::granularity): Units of deltaX and deltaY.

  • dom/WheelEvent.idl: Add initWebKitWheelEvent() to JavaScript. This is

the same as the initWheelEvent ObjC method. As the DOM Level 3 Events
specification is still a working draft and subject to change, prefix
'WebKit' to the method signature to indicate experimental support.

  • page/EventHandler.cpp: Move the scroll handling from

handleWheelEvent() to defaultWheelEventHandler(), which is executed on
both PlatformWheelEvents and JavaScript WheelEvents.
(WebCore::scrollNode): Renamed from scrollAndAcceptEvent(). Remove
the PlatformWheelEvent from the argument list and instead return a
boolean indicating if the scroll event was accepted.
(WebCore::EventHandler::handleWheelEvent): Move scrolling code from here
(WebCore::EventHandler::defaultWheelEventHandler): ...to here.

  • page/EventHandler.h: Add function signature.

LayoutTests: Add a test for the patch to https://bugs.webkit.org/show_bug.cgi?id=35566.
These can be run manually or from DRT.

Patch by Andy Estes <aestes@apple.com> on 2010-03-02
Reviewed by Maciej Stachowiak.

  • fast/events/wheelevent-in-scrolling-div-expected.txt: Added.
  • fast/events/wheelevent-in-scrolling-div.html: Added.
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r55433 r55436  
     12010-03-02  Andy Estes  <aestes@apple.com>
     2
     3        Reviewed by Maciej Stachowiak.
     4
     5        Add a test for the patch to https://bugs.webkit.org/show_bug.cgi?id=35566.
     6        These can be run manually or from DRT.
     7
     8        * fast/events/wheelevent-in-scrolling-div-expected.txt: Added.
     9        * fast/events/wheelevent-in-scrolling-div.html: Added.
     10
    1112010-03-02  Mark Rowe  <mrowe@apple.com>
    212
  • trunk/WebCore/ChangeLog

    r55433 r55436  
     12010-03-02  Andy Estes  <aestes@apple.com>
     2
     3        Reviewed by Maciej Stachowiak.
     4
     5        Add the capability to create and dispatch a WheelEvent in JavaScript.
     6        Ensure the event's default handler is triggered in the same way as it is
     7        during a PlatformWheelEvent.
     8
     9        https://bugs.webkit.org/show_bug.cgi?id=35566
     10
     11        Test: fast/events/wheelevent-in-scrolling-div.html
     12
     13        * dom/Node.cpp: Ensure that the default behavior (scrolling) occurs for
     14        wheel events originating both from the platform and from
     15        JavaScript/ObjC.
     16        (WebCore::Node::dispatchWheelEvent): Instantiate new WheelEvent with
     17        the graunularity of the PlatformWheelEvent.
     18        (WebCore::Node::defaultEventHandler): Add support for mousewheel events.
     19        * dom/WheelEvent.cpp: Add three new member variables: m_deltaX, m_deltaY
     20        and m_granularity.  m_deltaX and m_deltaY differ from m_wheelDeltaX and
     21        m_wheelDeltaY, which are the number of wheel ticks multiplied by 120 for
     22        IE compatibility.
     23        (WebCore::WheelEvent::WheelEvent): Initialize new member variables.
     24        (WebCore::WheelEvent::initWheelEvent): Same.
     25        (WebCore::WheelEvent::initWebKitWheelEvent): Same.
     26        * dom/WheelEvent.h: See WheelEvent.cpp.
     27        (WebCore::WheelEvent::): Add Granularity enum (Pixel, Line, Page).
     28        (WebCore::WheelEvent::create): Add new arguments.
     29        (WebCore::WheelEvent::deltaX): Amount of scroll in x direction.
     30        (WebCore::WheelEvent::deltaY): Amount of scroll in y direction.
     31        (WebCore::WheelEvent::granularity): Units of deltaX and deltaY.
     32        * dom/WheelEvent.idl: Add initWebKitWheelEvent() to JavaScript.  This is
     33        the same as the initWheelEvent ObjC method.  As the DOM Level 3 Events
     34        specification is still a working draft and subject to change, prefix
     35        'WebKit' to the method signature to indicate experimental support.
     36        * page/EventHandler.cpp: Move the scroll handling from
     37        handleWheelEvent() to defaultWheelEventHandler(), which is executed on
     38        both PlatformWheelEvents and JavaScript WheelEvents.
     39        (WebCore::scrollNode): Renamed from scrollAndAcceptEvent().  Remove
     40        the PlatformWheelEvent from the argument list and instead return a
     41        boolean indicating if the scroll event was accepted.
     42        (WebCore::EventHandler::handleWheelEvent): Move scrolling code from here
     43        (WebCore::EventHandler::defaultWheelEventHandler): ...to here.
     44        * page/EventHandler.h: Add function signature.
     45
    1462010-03-02  Mark Rowe  <mrowe@apple.com>
    247
  • trunk/WebCore/dom/Node.cpp

    r54926 r55436  
    33 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2001 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
     5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
    66 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
    77 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
     
    29032903    }
    29042904   
    2905     RefPtr<WheelEvent> we = WheelEvent::create(e.wheelTicksX(), e.wheelTicksY(),
     2905    WheelEvent::Granularity granularity;
     2906    switch (e.granularity()) {
     2907    case ScrollByPageWheelEvent:
     2908        granularity = WheelEvent::Page;
     2909        break;
     2910    case ScrollByPixelWheelEvent:
     2911    default:
     2912        granularity = WheelEvent::Pixel;
     2913        break;
     2914    }
     2915   
     2916    RefPtr<WheelEvent> we = WheelEvent::create(e.wheelTicksX(), e.wheelTicksY(), e.deltaX(), e.deltaY(), granularity,
    29062917        document()->defaultView(), e.globalX(), e.globalY(), adjustedPageX, adjustedPageY,
    29072918        e.ctrlKey(), e.altKey(), e.shiftKey(), e.metaKey());
     
    29092920    we->setAbsoluteLocation(IntPoint(pos.x(), pos.y()));
    29102921
    2911     if (!dispatchEvent(we.release()))
     2922    if (!dispatchEvent(we) || we->defaultHandled())
    29122923        e.accept();
     2924
     2925    we.release();
    29132926}
    29142927
     
    29672980        }
    29682981#endif
     2982    } else if (eventType == eventNames().mousewheelEvent && event->isWheelEvent()) {
     2983        WheelEvent* wheelEvent = static_cast<WheelEvent*>(event);
     2984       
     2985        // If we don't have a renderer, send the wheel event to the first node we find with a renderer.
     2986        // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll.
     2987        Node* startNode = this;
     2988        while (startNode && !startNode->renderer())
     2989            startNode = startNode->parent();
     2990       
     2991        if (startNode && startNode->renderer())
     2992            if (Frame* frame = document()->frame())
     2993                frame->eventHandler()->defaultWheelEventHandler(startNode, wheelEvent);
    29692994    }
    29702995}
  • trunk/WebCore/dom/WheelEvent.cpp

    r41746 r55436  
    33 * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
    44 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
    5  * Copyright (C) 2003, 2005, 2006, 2008 Apple Inc. All rights reserved.
     5 * Copyright (C) 2003, 2005, 2006, 2008, 2010 Apple Inc. All rights reserved.
    66 *
    77 * This library is free software; you can redistribute it and/or
     
    3232    : m_wheelDeltaX(0)
    3333    , m_wheelDeltaY(0)
     34    , m_rawDeltaX(0)
     35    , m_rawDeltaY(0)
     36    , m_granularity(Pixel)
    3437{
    3538}
    3639
    37 WheelEvent::WheelEvent(float wheelTicksX, float wheelTicksY, PassRefPtr<AbstractView> view,
     40WheelEvent::WheelEvent(float wheelTicksX, float wheelTicksY, float rawDeltaX, float rawDeltaY,
     41                       Granularity granularity, PassRefPtr<AbstractView> view,
    3842                       int screenX, int screenY, int pageX, int pageY,
    3943                       bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
    4044    : MouseRelatedEvent(eventNames().mousewheelEvent,
    41                         true, true, view, 0, screenX, screenY, pageX, pageY, 
     45                        true, true, view, 0, screenX, screenY, pageX, pageY,
    4246                        ctrlKey, altKey, shiftKey, metaKey)
    4347    , m_wheelDeltaX(lroundf(wheelTicksX * 120))
    4448    , m_wheelDeltaY(lroundf(wheelTicksY * 120)) // Normalize to the Windows 120 multiple
     49    , m_rawDeltaX(rawDeltaX)
     50    , m_rawDeltaY(rawDeltaY)
     51    , m_granularity(granularity)
    4552{
    4653}
    4754
    48 void WheelEvent::initWheelEvent(int wheelDeltaX, int wheelDeltaY, PassRefPtr<AbstractView> view,
     55void WheelEvent::initWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtr<AbstractView> view,
    4956                                int screenX, int screenY, int pageX, int pageY,
    5057                                bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
     
    6168    m_shiftKey = shiftKey;
    6269    m_metaKey = metaKey;
    63     m_wheelDeltaX = wheelDeltaX;
    64     m_wheelDeltaY = wheelDeltaY;
     70   
     71    // Normalize to the Windows 120 multiple
     72    m_wheelDeltaX = rawDeltaX * 120;
     73    m_wheelDeltaY = rawDeltaY * 120;
     74   
     75    m_rawDeltaX = rawDeltaX;
     76    m_rawDeltaY = rawDeltaY;
     77    m_granularity = Pixel;
    6578   
    6679    initCoordinates(pageX, pageY);
    6780}
    6881
     82void WheelEvent::initWebKitWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtr<AbstractView> view,
     83                                      int screenX, int screenY, int pageX, int pageY,
     84                                      bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
     85{
     86    initWheelEvent(rawDeltaX, rawDeltaY, view, screenX, screenY, pageX, pageY,
     87                   ctrlKey, altKey, shiftKey, metaKey);
     88}
    6989
    7090bool WheelEvent::isWheelEvent() const
  • trunk/WebCore/dom/WheelEvent.h

    r41746 r55436  
    33 * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
    44 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
    5  * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
     5 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2010 Apple Inc. All rights reserved.
    66 *
    77 * This library is free software; you can redistribute it and/or
     
    3232    class WheelEvent : public MouseRelatedEvent {
    3333    public:
     34        enum Granularity { Pixel, Line, Page };
     35
    3436        static PassRefPtr<WheelEvent> create()
    3537        {
    3638            return adoptRef(new WheelEvent);
    3739        }
    38         static PassRefPtr<WheelEvent> create(float wheelTicksX, float wheelTicksY, PassRefPtr<AbstractView> view,
     40        static PassRefPtr<WheelEvent> create(float wheelTicksX, float wheelTicksY,
     41            float rawDeltaX, float rawDeltaY, Granularity granularity, PassRefPtr<AbstractView> view,
    3942            int screenX, int screenY, int pageX, int pageY,
    4043            bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
    4144        {
    42             return adoptRef(new WheelEvent(wheelTicksX, wheelTicksY, view, screenX, screenY, pageX, pageY,
     45            return adoptRef(new WheelEvent(wheelTicksX, wheelTicksY, rawDeltaX, rawDeltaY,
     46                granularity, view, screenX, screenY, pageX, pageY,
    4347                ctrlKey, altKey, shiftKey, metaKey));
    4448        }
    4549
    46         void initWheelEvent(int wheelDeltaX, int wheelDeltaY, PassRefPtr<AbstractView>,
     50        void initWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtr<AbstractView>,
    4751                            int screenX, int screenY, int pageX, int pageY,
    4852                            bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
     53
     54        void initWebKitWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtr<AbstractView>,
     55                                  int screenX, int screenY, int pageX, int pageY,
     56                                  bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
    4957
    5058        int wheelDelta() const { if (m_wheelDeltaY == 0) return m_wheelDeltaX; return m_wheelDeltaY; }
    5159        int wheelDeltaX() const { return m_wheelDeltaX; }
    5260        int wheelDeltaY() const { return m_wheelDeltaY; }
     61        int rawDeltaX() const { return m_rawDeltaX; }
     62        int rawDeltaY() const { return m_rawDeltaY; }
     63        Granularity granularity() const { return m_granularity; }
    5364
    5465        // Needed for Objective-C legacy support
     
    5768    private:
    5869        WheelEvent();
    59         WheelEvent(float wheelTicksX, float wheelTicksY, PassRefPtr<AbstractView>,
     70        WheelEvent(float wheelTicksX, float wheelTicksY, float rawDeltaX, float rawDeltaY,
     71                   Granularity granularity, PassRefPtr<AbstractView>,
    6072                   int screenX, int screenY, int pageX, int pageY,
    6173                   bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
    6274
    6375        virtual bool isWheelEvent() const;
    64 
     76       
    6577        int m_wheelDeltaX;
    6678        int m_wheelDeltaY;
     79
     80        int m_rawDeltaX;
     81        int m_rawDeltaY;
     82        Granularity m_granularity;
    6783    };
    6884
  • trunk/WebCore/dom/WheelEvent.idl

    r52537 r55436  
    11/*
    2  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
    33 * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
    44 *
     
    5858                            in boolean metaKey);
    5959#endif /* !defined(LANGUAGE_JAVASCRIPT) */
     60
     61#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
     62        void initWebKitWheelEvent(in long wheelDeltaX,
     63                                  in long wheelDeltaY,
     64                                  in DOMWindow view,
     65                                  in long screenX,
     66                                  in long screenY,
     67                                  in long clientX,
     68                                  in long clientY,
     69                                  in boolean ctrlKey,
     70                                  in boolean altKey,
     71                                  in boolean shiftKey,
     72                                  in boolean metaKey);
     73#endif /* defined(LANGUAGE_JAVASCRIPT) */
    6074    };
    61 
    6275}
  • trunk/WebCore/page/EventHandler.cpp

    r55353 r55436  
    11/*
    2  * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
    33 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
    44 *
     
    6666#include "Settings.h"
    6767#include "TextEvent.h"
     68#include "WheelEvent.h"
    6869#include "htmlediting.h" // for comparePositions()
    6970#include <wtf/StdLibExtras.h>
     
    108109static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
    109110
    110 static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node, Node** stopNode)
     111static inline bool scrollNode(float delta, WheelEvent::Granularity granularity, ScrollDirection positiveDirection, ScrollDirection negativeDirection, Node* node, Node** stopNode)
    111112{
    112113    if (!delta)
    113         return;
    114        
     114        return false;
     115   
    115116    // Find the nearest enclosing box.
    116117    RenderBox* enclosingBox = node->renderer()->enclosingBox();
    117118
    118     if (e.granularity() == ScrollByPageWheelEvent) {
    119         if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1, stopNode))
    120             e.accept();
    121         return;
    122     }
    123 
    124     float pixelsToScroll = delta > 0 ? delta : -delta;
    125     if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll, stopNode))
    126         e.accept();
     119    float absDelta = delta > 0 ? delta : -delta;
     120   
     121    if (granularity == WheelEvent::Page)
     122        return enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, absDelta, stopNode);
     123
     124    if (granularity == WheelEvent::Line)
     125        return enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByLine, absDelta, stopNode);
     126
     127    if (granularity == WheelEvent::Pixel)
     128        return enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, absDelta, stopNode);
     129       
     130    return false;
    127131}
    128132
     
    18661870        if (e.isAccepted())
    18671871            return true;
    1868 
    1869         // If we don't have a renderer, send the wheel event to the first node we find with a renderer.
    1870         // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll.
    1871         while (node && !node->renderer())
    1872             node = node->parent();
    1873 
    1874         if (node && node->renderer()) {
    1875             // Just break up into two scrolls if we need to.  Diagonal movement on
    1876             // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
    1877             Node* stopNode = m_previousWheelScrolledNode.get();
    1878             scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node, &stopNode);
    1879             scrollAndAcceptEvent(e.deltaY(), ScrollUp, ScrollDown, e, node, &stopNode);
    1880             if (!m_useLatchedWheelEventNode)
    1881                 m_previousWheelScrolledNode = stopNode;
    1882         }
    18831872    }
    18841873
     
    18921881    view->wheelEvent(e);
    18931882    return e.isAccepted();
     1883}
     1884   
     1885void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEvent)
     1886{
     1887    if (!startNode || !wheelEvent)
     1888        return;
     1889   
     1890    Node* stopNode = m_previousWheelScrolledNode.get();
     1891   
     1892    // Break up into two scrolls if we need to.  Diagonal movement on
     1893    // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
     1894    if (scrollNode(wheelEvent->rawDeltaX(), wheelEvent->granularity(), ScrollLeft, ScrollRight, startNode, &stopNode))
     1895        wheelEvent->setDefaultHandled();
     1896   
     1897    if (scrollNode(wheelEvent->rawDeltaY(), wheelEvent->granularity(), ScrollUp, ScrollDown, startNode, &stopNode))
     1898        wheelEvent->setDefaultHandled();
     1899   
     1900    if (!m_useLatchedWheelEventNode)
     1901        m_previousWheelScrolledNode = stopNode;
    18941902}
    18951903
  • trunk/WebCore/page/EventHandler.h

    r55287 r55436  
    11/*
    2  * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6868class TextEvent;
    6969class TouchEvent;
     70class WheelEvent;
    7071class Widget;
    7172   
     
    147148    bool handleMouseReleaseEvent(const PlatformMouseEvent&);
    148149    bool handleWheelEvent(PlatformWheelEvent&);
     150    void defaultWheelEventHandler(Node*, WheelEvent*);
    149151
    150152#if ENABLE(CONTEXT_MENUS)
Note: See TracChangeset for help on using the changeset viewer.