Changeset 81057 in webkit


Ignore:
Timestamp:
Mar 14, 2011 2:22:32 PM (13 years ago)
Author:
aestes@apple.com
Message:

2011-03-13 Andy Estes <aestes@apple.com>

Reviewed by Darin Adler.

Timer-based events should inherit the user gesture state of their
originating event in certain cases.
https://bugs.webkit.org/show_bug.cgi?id=55104

  • fast/events/popup-blocking-timers-expected.txt: Added.
  • fast/events/popup-blocking-timers.html: Added.

2011-03-14 Andy Estes <aestes@apple.com>

Reviewed by Darin Adler.

Timer-based events should inherit the user gesture state of their
originating event in certain cases.
https://bugs.webkit.org/show_bug.cgi?id=55104

If a timer is installed by a gesture-originated event and will fire
within one second, the timer-initiated event should behave as if it
were also initiated by a user gesture. Multi-shot timers should only
get this behavior on their first execution. Nested timers should not
get this behavior. This makes us compatible with Gecko when handling
popups and file chooser dialogs created from timer events.

Test: fast/events/popup-blocking-timers.html

  • page/DOMTimer.cpp: (WebCore::timeoutId): Create a helper function so that m_timeoutId can be initialized in the data member initialization list. (WebCore::shouldForwardUserGesture): Ditto, but for m_shouldForwardUserGesture. (WebCore::DOMTimer::DOMTimer): Move initialization of data members from the ctor body to the data member initialization list. Also rename the argument 'timeout' to 'interval'. (WebCore::DOMTimer::fired): Create a UserGestureIndicator and set its state based on the value of m_shouldForwardUserGesture. (WebCore::DOMTimer::adjustMinimumTimerInterval): m_originalTimeout was renamed to m_originalInterval.
  • page/DOMTimer.h: Add m_shouldForwardUserGesture and rename m_originalTimeout to m_originalInterval.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r81056 r81057  
     12011-03-13  Andy Estes  <aestes@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        Timer-based events should inherit the user gesture state of their
     6        originating event in certain cases.
     7        https://bugs.webkit.org/show_bug.cgi?id=55104
     8
     9        * fast/events/popup-blocking-timers-expected.txt: Added.
     10        * fast/events/popup-blocking-timers.html: Added.
     11
    1122011-03-09  Levi Weintraub  <leviw@chromium.org>
    213
  • trunk/Source/WebCore/ChangeLog

    r81056 r81057  
     12011-03-14  Andy Estes  <aestes@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        Timer-based events should inherit the user gesture state of their
     6        originating event in certain cases.
     7        https://bugs.webkit.org/show_bug.cgi?id=55104
     8
     9        If a timer is installed by a gesture-originated event and will fire
     10        within one second, the timer-initiated event should behave as if it
     11        were also initiated by a user gesture. Multi-shot timers should only
     12        get this behavior on their first execution. Nested timers should not
     13        get this behavior. This makes us compatible with Gecko when handling
     14        popups and file chooser dialogs created from timer events.
     15
     16        Test: fast/events/popup-blocking-timers.html
     17
     18        * page/DOMTimer.cpp:
     19        (WebCore::timeoutId): Create a helper function so that m_timeoutId can
     20        be initialized in the data member initialization list.
     21        (WebCore::shouldForwardUserGesture): Ditto, but for
     22        m_shouldForwardUserGesture.
     23        (WebCore::DOMTimer::DOMTimer): Move initialization of data members from
     24        the ctor body to the data member initialization list. Also rename the
     25        argument 'timeout' to 'interval'.
     26        (WebCore::DOMTimer::fired): Create a UserGestureIndicator and set its
     27        state based on the value of m_shouldForwardUserGesture.
     28        (WebCore::DOMTimer::adjustMinimumTimerInterval): m_originalTimeout was
     29        renamed to m_originalInterval.
     30        * page/DOMTimer.h: Add m_shouldForwardUserGesture and rename
     31        m_originalTimeout to m_originalInterval.
     32
    1332011-03-09  Levi Weintraub  <leviw@chromium.org>
    234
  • trunk/Source/WebCore/page/DOMTimer.cpp

    r79455 r81057  
    3131#include "ScheduledAction.h"
    3232#include "ScriptExecutionContext.h"
     33#include "UserGestureIndicator.h"
    3334#include <wtf/HashSet.h>
    3435#include <wtf/StdLibExtras.h>
     
    3839namespace WebCore {
    3940
     41static const int maxIntervalForUserGestureForwarding = 1000; // One second matches Gecko.
    4042static const int maxTimerNestingLevel = 5;
    4143static const double oneMillisecond = 0.001;
     
    4345
    4446static int timerNestingLevel = 0;
    45 
    46 DOMTimer::DOMTimer(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> action, int timeout, bool singleShot)
    47     : SuspendableTimer(context)
    48     , m_action(action)
    49     , m_originalTimeout(timeout)
     47   
     48static int timeoutId()
    5049{
    5150    static int lastUsedTimeoutId = 0;
     
    5453    if (lastUsedTimeoutId <= 0)
    5554        lastUsedTimeoutId = 1;
    56     m_timeoutId = lastUsedTimeoutId;
     55    return lastUsedTimeoutId;
     56}
     57   
     58static inline bool shouldForwardUserGesture(int interval, int nestingLevel)
     59{
     60    return UserGestureIndicator::processingUserGesture()
     61        && interval <= maxIntervalForUserGestureForwarding
     62        && nestingLevel == 1; // Gestures should not be forwarded to nested timers.
     63}
    5764
    58     m_nestingLevel = timerNestingLevel + 1;
    59 
     65DOMTimer::DOMTimer(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> action, int interval, bool singleShot)
     66    : SuspendableTimer(context)
     67    , m_timeoutId(timeoutId())
     68    , m_nestingLevel(timerNestingLevel + 1)
     69    , m_action(action)
     70    , m_originalInterval(interval)
     71    , m_shouldForwardUserGesture(shouldForwardUserGesture(interval, m_nestingLevel))
     72{
    6073    scriptExecutionContext()->addTimeout(m_timeoutId, this);
    6174
    62     double intervalMilliseconds = intervalClampedToMinimum(timeout, context->minimumTimerInterval());
     75    double intervalMilliseconds = intervalClampedToMinimum(interval, context->minimumTimerInterval());
    6376    if (singleShot)
    6477        startOneShot(intervalMilliseconds);
     
    102115    ScriptExecutionContext* context = scriptExecutionContext();
    103116    timerNestingLevel = m_nestingLevel;
     117   
     118    UserGestureIndicator gestureIndicator(m_shouldForwardUserGesture ? DefinitelyProcessingUserGesture : PossiblyProcessingUserGesture);
     119   
     120    // Only the first execution of a multi-shot timer should get an affirmative user gesture indicator.
     121    m_shouldForwardUserGesture = false;
    104122
    105123    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireTimer(context, m_timeoutId);
     
    156174
    157175    double newMinimumInterval = scriptExecutionContext()->minimumTimerInterval();
    158     double newClampedInterval = intervalClampedToMinimum(m_originalTimeout, newMinimumInterval);
     176    double newClampedInterval = intervalClampedToMinimum(m_originalInterval, newMinimumInterval);
    159177
    160178    if (repeatInterval()) {
     
    163181    }
    164182
    165     double previousClampedInterval = intervalClampedToMinimum(m_originalTimeout, oldMinimumTimerInterval);
     183    double previousClampedInterval = intervalClampedToMinimum(m_originalInterval, oldMinimumTimerInterval);
    166184    augmentFireInterval(newClampedInterval - previousClampedInterval);
    167185}
  • trunk/Source/WebCore/page/DOMTimer.h

    r78620 r81057  
    5656
    5757    private:
    58         DOMTimer(ScriptExecutionContext*, PassOwnPtr<ScheduledAction>, int timeout, bool singleShot);
     58        DOMTimer(ScriptExecutionContext*, PassOwnPtr<ScheduledAction>, int interval, bool singleShot);
    5959        virtual void fired();
    6060
     
    6969        int m_nestingLevel;
    7070        OwnPtr<ScheduledAction> m_action;
    71         int m_originalTimeout;
     71        int m_originalInterval;
     72        bool m_shouldForwardUserGesture;
    7273        static double s_minDefaultTimerInterval;
    7374    };
Note: See TracChangeset for help on using the changeset viewer.