summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/page/DOMTimer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/page/DOMTimer.cpp')
-rw-r--r--Source/WebCore/page/DOMTimer.cpp40
1 files changed, 29 insertions, 11 deletions
diff --git a/Source/WebCore/page/DOMTimer.cpp b/Source/WebCore/page/DOMTimer.cpp
index eaca8f2..0a94e7e 100644
--- a/Source/WebCore/page/DOMTimer.cpp
+++ b/Source/WebCore/page/DOMTimer.cpp
@@ -30,6 +30,7 @@
#include "InspectorInstrumentation.h"
#include "ScheduledAction.h"
#include "ScriptExecutionContext.h"
+#include "UserGestureIndicator.h"
#include <wtf/HashSet.h>
#include <wtf/StdLibExtras.h>
@@ -37,29 +38,41 @@ using namespace std;
namespace WebCore {
+static const int maxIntervalForUserGestureForwarding = 1000; // One second matches Gecko.
static const int maxTimerNestingLevel = 5;
static const double oneMillisecond = 0.001;
double DOMTimer::s_minDefaultTimerInterval = 0.010; // 10 milliseconds
static int timerNestingLevel = 0;
-
-DOMTimer::DOMTimer(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> action, int timeout, bool singleShot)
- : SuspendableTimer(context)
- , m_action(action)
- , m_originalTimeout(timeout)
+
+static int timeoutId()
{
static int lastUsedTimeoutId = 0;
++lastUsedTimeoutId;
// Avoid wraparound going negative on us.
if (lastUsedTimeoutId <= 0)
lastUsedTimeoutId = 1;
- m_timeoutId = lastUsedTimeoutId;
-
- m_nestingLevel = timerNestingLevel + 1;
+ return lastUsedTimeoutId;
+}
+
+static inline bool shouldForwardUserGesture(int interval, int nestingLevel)
+{
+ return UserGestureIndicator::processingUserGesture()
+ && interval <= maxIntervalForUserGestureForwarding
+ && nestingLevel == 1; // Gestures should not be forwarded to nested timers.
+}
+DOMTimer::DOMTimer(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> action, int interval, bool singleShot)
+ : SuspendableTimer(context)
+ , m_timeoutId(timeoutId())
+ , m_nestingLevel(timerNestingLevel + 1)
+ , m_action(action)
+ , m_originalInterval(interval)
+ , m_shouldForwardUserGesture(shouldForwardUserGesture(interval, m_nestingLevel))
+{
scriptExecutionContext()->addTimeout(m_timeoutId, this);
- double intervalMilliseconds = intervalClampedToMinimum(timeout, context->minimumTimerInterval());
+ double intervalMilliseconds = intervalClampedToMinimum(interval, context->minimumTimerInterval());
if (singleShot)
startOneShot(intervalMilliseconds);
else
@@ -101,6 +114,11 @@ void DOMTimer::fired()
{
ScriptExecutionContext* context = scriptExecutionContext();
timerNestingLevel = m_nestingLevel;
+
+ UserGestureIndicator gestureIndicator(m_shouldForwardUserGesture ? DefinitelyProcessingUserGesture : PossiblyProcessingUserGesture);
+
+ // Only the first execution of a multi-shot timer should get an affirmative user gesture indicator.
+ m_shouldForwardUserGesture = false;
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireTimer(context, m_timeoutId);
@@ -155,14 +173,14 @@ void DOMTimer::adjustMinimumTimerInterval(double oldMinimumTimerInterval)
return;
double newMinimumInterval = scriptExecutionContext()->minimumTimerInterval();
- double newClampedInterval = intervalClampedToMinimum(m_originalTimeout, newMinimumInterval);
+ double newClampedInterval = intervalClampedToMinimum(m_originalInterval, newMinimumInterval);
if (repeatInterval()) {
augmentRepeatInterval(newClampedInterval - repeatInterval());
return;
}
- double previousClampedInterval = intervalClampedToMinimum(m_originalTimeout, oldMinimumTimerInterval);
+ double previousClampedInterval = intervalClampedToMinimum(m_originalInterval, oldMinimumTimerInterval);
augmentFireInterval(newClampedInterval - previousClampedInterval);
}