Commit 7bf42ee7 authored by kbr@google.com's avatar kbr@google.com

2011-02-15 Kenneth Russell <kbr@google.com>

        Reviewed by Darin Fisher.

        Allow controlling minimum DOMTimer interval on a per-page basis
        https://bugs.webkit.org/show_bug.cgi?id=54312

        Implemented new method setMinimumTimerInterval in
        LayoutTestController for all ports.

        * DumpRenderTree/LayoutTestController.cpp:
        (setMinimumTimerIntervalCallback):
        (LayoutTestController::staticFunctions):
        * DumpRenderTree/LayoutTestController.h:
        * DumpRenderTree/chromium/LayoutTestController.cpp:
        (LayoutTestController::LayoutTestController):
        (LayoutTestController::setMinimumTimerInterval):
        * DumpRenderTree/chromium/LayoutTestController.h:
        * DumpRenderTree/chromium/WebViewHost.cpp:
        (WebViewHost::reset):
        * DumpRenderTree/gtk/DumpRenderTree.cpp:
        (resetDefaultsToConsistentValues):
        * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
        (LayoutTestController::setMinimumTimerInterval):
        * DumpRenderTree/mac/DumpRenderTree.mm:
        (resetWebViewToConsistentStateBeforeTesting):
        * DumpRenderTree/mac/LayoutTestControllerMac.mm:
        (LayoutTestController::setMinimumTimerInterval):
        * DumpRenderTree/qt/DumpRenderTreeQt.cpp:
        (WebCore::WebPage::resetSettings):
        * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
        (LayoutTestController::setMinimumTimerInterval):
        * DumpRenderTree/qt/LayoutTestControllerQt.h:
        * DumpRenderTree/win/DumpRenderTree.cpp:
        (resetWebViewToConsistentStateBeforeTesting):
        * DumpRenderTree/win/LayoutTestControllerWin.cpp:
        (LayoutTestController::setMinimumTimerInterval):
2011-02-15  Kenneth Russell  <kbr@google.com>

        Reviewed by Darin Fisher.

        Allow controlling minimum DOMTimer interval on a per-page basis
        https://bugs.webkit.org/show_bug.cgi?id=54312

        * fast/dom/timer-increase-min-interval-and-reset-part-1-expected.txt: Added.
        * fast/dom/timer-increase-min-interval-and-reset-part-1.html: Added.
        * fast/dom/timer-increase-min-interval-and-reset-part-2-expected.txt: Added.
        * fast/dom/timer-increase-min-interval-and-reset-part-2.html: Added.
          - Chained tests (the assumption is that the run-webkit-tests
            harness will run them sequentially, which is a reasonably good
            assumption) which verify that the minimum timer interval is
            reset between tests.
        * fast/dom/timer-increase-min-interval-expected.txt: Added.
        * fast/dom/timer-increase-min-interval.html: Added.
          - Verifies that increasing the minimum timer interval causes
            fast timers to run slowly.
        * fast/dom/timer-increase-then-decrease-min-interval-expected.txt: Added.
        * fast/dom/timer-increase-then-decrease-min-interval.html: Added.
          - Verifies that decreasing the minimum timer interval causes
            previously slowed-down timers to be reevaluated immediately.
2011-02-15  Kenneth Russell  <kbr@google.com>

        Reviewed by Darin Fisher.

        Allow controlling minimum DOMTimer interval on a per-page basis
        https://bugs.webkit.org/show_bug.cgi?id=54312

        * public/WebSettings.h:
          - Added setMinimumTimerInterval.
        * src/WebKit.cpp:
        (WebKit::initialize):
          - Added FIXME to remove setting of page's default timer interval.
        * src/WebSettingsImpl.cpp:
        (WebKit::WebSettingsImpl::setMinimumTimerInterval):
          - Implemented new method on WebSettings.
        * src/WebSettingsImpl.h:
2011-02-15  Kenneth Russell  <kbr@google.com>

        Reviewed by Darin Fisher.

        Allow controlling minimum DOMTimer interval on a per-page basis
        https://bugs.webkit.org/show_bug.cgi?id=54312

        Added needed methods to implement LayoutTestController's new
        setMinimumTimerInterval method.

        * WebCoreSupport/DumpRenderTreeSupportQt.cpp:
        (DumpRenderTreeSupportQt::defaultMinimumTimerInterval):
        (DumpRenderTreeSupportQt::setMinimumTimerInterval):
        * WebCoreSupport/DumpRenderTreeSupportQt.h:
2011-02-15  Kenneth Russell  <kbr@google.com>

        Reviewed by Darin Fisher.

        Allow controlling minimum DOMTimer interval on a per-page basis
        https://bugs.webkit.org/show_bug.cgi?id=54312

        Added needed methods to implement LayoutTestController's new
        setMinimumTimerInterval method.

        * WebCoreSupport/DumpRenderTreeSupportGtk.cpp:
        (DumpRenderTreeSupportGtk::defaultMinimumTimerInterval):
        (DumpRenderTreeSupportGtk::setMinimumTimerInterval):
        * WebCoreSupport/DumpRenderTreeSupportGtk.h:
2011-02-15  Kenneth Russell  <kbr@google.com>

        Reviewed by Darin Fisher.

        Allow controlling minimum DOMTimer interval on a per-page basis
        https://bugs.webkit.org/show_bug.cgi?id=54312

        Added needed methods to implement LayoutTestController's new
        setMinimumTimerInterval method. Includes whitespace-only change to
        WebKit.idl to trigger proper rebuild on bots; will be removed in
        subsequent checkin.

        * Interfaces/IWebViewPrivate.idl:
        * Interfaces/WebKit.idl:
        * WebView.cpp:
        (WebView::initWithFrame):
        (WebView::defaultMinimumTimerInterval):
        (WebView::setMinimumTimerInterval):
        * WebView.h:
2011-02-15  Kenneth Russell  <kbr@google.com>

        Reviewed by Darin Fisher.

        Allow controlling minimum DOMTimer interval on a per-page basis
        https://bugs.webkit.org/show_bug.cgi?id=54312

        Added needed methods to implement LayoutTestController's new
        setMinimumTimerInterval method.

        * WebView/WebView.mm:
        (-[WebView _commonInitializationWithFrameName:groupName:usesDocumentViews:]):
        (+[WebView _defaultMinimumTimerInterval]):
        (-[WebView _setMinimumTimerInterval:]):
        * WebView/WebViewPrivate.h:
2011-02-15  Kenneth Russell  <kbr@google.com>

        Reviewed by Darin Fisher.

        Allow controlling minimum DOMTimer interval on a per-page basis
        https://bugs.webkit.org/show_bug.cgi?id=54312

        Renamed DOMTimer::minTimerInterval and setMinTimerInterval to
        defaultMinTimerInterval and setDefaultMinTimerInterval, made them
        private and exposed them via Settings::defaultMinDOMTimerInterval
        and setDefaultMinDOMTimerInterval. Added new
        Settings::setMinDOMTimerInterval and minDOMTimerInterval.

        The storage for the minimum timer interval currently lives in the
        Page, though this could be moved to the Settings object if
        desired. The accessor methods on the Page are private and exposed
        to Settings by making Settings a friend, so the abstraction
        barrier is clear at the API level.

        Adjusting the interval both upward and downward may cause the fire
        times of the active timers on the page to be adjusted, if they
        would be affected by the clamping value. This is needed to reduce
        latency when bringing a tab to the foreground, in particular if
        the minimum timer interval was decreased from a very high value to
        a very low value.

        A new method, setMinimumTimerInterval, has been added to
        LayoutTestController, implemented in all ports of DumpRenderTree,
        and used in new layout tests.

        Ideally changing the page's minimum timer interval would affect
        dedicated workers, but this is too much to do in an initial patch,
        so a FIXME has been added.

        Tested with:
          - The new layout tests on the WebKit Mac and Chromium (Mac,
            Linux) DRT ports.
          - Hooked up the new API in Chromium and ran some simple manual
            tests.

        Tests: fast/dom/timer-increase-min-interval-and-reset-part-1.html
               fast/dom/timer-increase-min-interval-and-reset-part-2.html
               fast/dom/timer-increase-min-interval.html
               fast/dom/timer-increase-then-decrease-min-interval.html

        * WebCore.exp.in:
        * dom/Document.cpp:
        (WebCore::Document::minimumTimerInterval):
        * dom/Document.h:
        * dom/ScriptExecutionContext.cpp:
        (WebCore::ScriptExecutionContext::adjustMinimumTimerInterval):
        (WebCore::ScriptExecutionContext::minimumTimerInterval):
        * dom/ScriptExecutionContext.h:
        * page/DOMTimer.cpp:
        (WebCore::DOMTimer::DOMTimer):
        (WebCore::DOMTimer::fired):
        (WebCore::DOMTimer::adjustMinimumTimerInterval):
        (WebCore::DOMTimer::intervalClampedToMinimum):
        * page/DOMTimer.h:
        (WebCore::DOMTimer::defaultMinTimerInterval):
        (WebCore::DOMTimer::setDefaultMinTimerInterval):
        * page/Page.cpp:
        (WebCore::Page::Page):
        (WebCore::Page::setMinimumTimerInterval):
        (WebCore::Page::minimumTimerInterval):
        * page/Page.h:
        * page/Settings.cpp:
        (WebCore::Settings::setDefaultMinDOMTimerInterval):
        (WebCore::Settings::defaultMinDOMTimerInterval):
        (WebCore::Settings::setMinDOMTimerInterval):
        (WebCore::Settings::minDOMTimerInterval):
        * page/Settings.h:
        * platform/Timer.h:
        (WebCore::TimerBase::augmentFireInterval):
        (WebCore::TimerBase::augmentRepeatInterval):
2011-02-15  Kenneth Russell  <kbr@google.com>

        Reviewed by Darin Fisher.

        Allow controlling minimum DOMTimer interval on a per-page basis
        https://bugs.webkit.org/show_bug.cgi?id=54312

        * WebProcess/WebPage/WebPage.cpp:
        (WebKit::WebPage::WebPage):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@78620 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 32178d57
2011-02-15 Kenneth Russell <kbr@google.com>
Reviewed by Darin Fisher.
Allow controlling minimum DOMTimer interval on a per-page basis
https://bugs.webkit.org/show_bug.cgi?id=54312
* fast/dom/timer-increase-min-interval-and-reset-part-1-expected.txt: Added.
* fast/dom/timer-increase-min-interval-and-reset-part-1.html: Added.
* fast/dom/timer-increase-min-interval-and-reset-part-2-expected.txt: Added.
* fast/dom/timer-increase-min-interval-and-reset-part-2.html: Added.
- Chained tests (the assumption is that the run-webkit-tests
harness will run them sequentially, which is a reasonably good
assumption) which verify that the minimum timer interval is
reset between tests.
* fast/dom/timer-increase-min-interval-expected.txt: Added.
* fast/dom/timer-increase-min-interval.html: Added.
- Verifies that increasing the minimum timer interval causes
fast timers to run slowly.
* fast/dom/timer-increase-then-decrease-min-interval-expected.txt: Added.
* fast/dom/timer-increase-then-decrease-min-interval.html: Added.
- Verifies that decreasing the minimum timer interval causes
previously slowed-down timers to be reevaluated immediately.
2011-02-15 Mihai Parparita <mihaip@chromium.org>
Unreviewed chromium-gpu baseline update. Unskip some tests that fail;
<html>
<head>
<script>
function log(msg) {
var element = document.createElement("div");
element.textContent = msg;
document.body.appendChild(element);
document.body.appendChild(document.createElement("br"));
}
function runTest() {
if (!window.layoutTestController) {
log("This test requires the LayoutTestController");
return;
}
layoutTestController.dumpAsText();
// Make timers run no more often than twice a second.
layoutTestController.setMinimumTimerInterval(0.5);
// Part 2 of this test (which will likely be executed immediately
// after this one by the harness) verifies that the minimum timer
// interval is reset between tests.
log("PASS");
}
</script>
</head>
<body onload="runTest()">
</body>
</html>
<html>
<head>
<script>
function log(msg) {
var element = document.createElement("div");
element.textContent = msg;
document.body.appendChild(element);
document.body.appendChild(document.createElement("br"));
}
var count = 0;
function fastTimeoutHandler() {
++count;
setTimeout(fastTimeoutHandler, 1);
}
function slowTimeoutHandler() {
// Note: the count threshold is tied somewhat to the
// maxTimerNestingLevel in DOMTimer.cpp.
if (count > 10)
log("PASS");
else
log("FAIL -- timeout ran " + count + " times");
layoutTestController.notifyDone();
}
function runTest() {
if (!window.layoutTestController) {
log("This test requires the LayoutTestController");
return;
}
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
// Timers should be running at full speed, not at the throttled
// rate set by part 1 of this test.
setTimeout(slowTimeoutHandler, 1000);
setTimeout(fastTimeoutHandler, 1);
}
</script>
</head>
<body onload="runTest()">
</body>
</html>
<html>
<head>
<script>
function log(msg) {
var element = document.createElement("div");
element.textContent = msg;
document.body.appendChild(element);
document.body.appendChild(document.createElement("br"));
}
var count = 0;
function fastTimeoutHandler() {
++count;
setTimeout(fastTimeoutHandler, 1);
}
function slowTimeoutHandler() {
// Note: the count threshold is tied somewhat to the
// maxTimerNestingLevel in DOMTimer.cpp.
if (count < 10)
log("PASS");
else
log("FAIL -- timeout ran " + count + " times");
layoutTestController.notifyDone();
}
function runTest() {
if (!window.layoutTestController) {
log("This test requires the LayoutTestController");
return;
}
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
// Make timers run no more often than twice a second.
layoutTestController.setMinimumTimerInterval(0.5);
setTimeout(slowTimeoutHandler, 1000);
setTimeout(fastTimeoutHandler, 1);
}
</script>
</head>
<body onload="runTest()">
</body>
</html>
<html>
<head>
<script>
function log(msg) {
var element = document.createElement("div");
element.textContent = msg;
document.body.appendChild(element);
document.body.appendChild(document.createElement("br"));
}
var count = 0;
function fastTimeoutHandler() {
++count;
setTimeout(fastTimeoutHandler, 1);
}
function slowTimeoutHandler() {
// Note: the count threshold is tied somewhat to the
// maxTimerNestingLevel in DOMTimer.cpp.
if (count > 10)
log("PASS");
else
log("FAIL -- timeout ran " + count + " times");
layoutTestController.notifyDone();
}
function runTest() {
if (!window.layoutTestController) {
log("This test requires the LayoutTestController");
return;
}
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
// Make timers run no more often than once per second.
layoutTestController.setMinimumTimerInterval(1.0);
setTimeout(slowTimeoutHandler, 500);
setTimeout(fastTimeoutHandler, 1);
// Allow timers to run quickly again.
// If this doesn't cause timers to get re-evaluated immediately,
// the fast timeout handler won't get called for up to a second,
// which would lead to poor responsiveness.
layoutTestController.setMinimumTimerInterval(0.004);
}
</script>
</head>
<body onload="runTest()">
</body>
</html>
2011-02-15 Kenneth Russell <kbr@google.com>
Reviewed by Darin Fisher.
Allow controlling minimum DOMTimer interval on a per-page basis
https://bugs.webkit.org/show_bug.cgi?id=54312
Renamed DOMTimer::minTimerInterval and setMinTimerInterval to
defaultMinTimerInterval and setDefaultMinTimerInterval, made them
private and exposed them via Settings::defaultMinDOMTimerInterval
and setDefaultMinDOMTimerInterval. Added new
Settings::setMinDOMTimerInterval and minDOMTimerInterval.
The storage for the minimum timer interval currently lives in the
Page, though this could be moved to the Settings object if
desired. The accessor methods on the Page are private and exposed
to Settings by making Settings a friend, so the abstraction
barrier is clear at the API level.
Adjusting the interval both upward and downward may cause the fire
times of the active timers on the page to be adjusted, if they
would be affected by the clamping value. This is needed to reduce
latency when bringing a tab to the foreground, in particular if
the minimum timer interval was decreased from a very high value to
a very low value.
A new method, setMinimumTimerInterval, has been added to
LayoutTestController, implemented in all ports of DumpRenderTree,
and used in new layout tests.
Ideally changing the page's minimum timer interval would affect
dedicated workers, but this is too much to do in an initial patch,
so a FIXME has been added.
Tested with:
- The new layout tests on the WebKit Mac and Chromium (Mac,
Linux) DRT ports.
- Hooked up the new API in Chromium and ran some simple manual
tests.
Tests: fast/dom/timer-increase-min-interval-and-reset-part-1.html
fast/dom/timer-increase-min-interval-and-reset-part-2.html
fast/dom/timer-increase-min-interval.html
fast/dom/timer-increase-then-decrease-min-interval.html
* WebCore.exp.in:
* dom/Document.cpp:
(WebCore::Document::minimumTimerInterval):
* dom/Document.h:
* dom/ScriptExecutionContext.cpp:
(WebCore::ScriptExecutionContext::adjustMinimumTimerInterval):
(WebCore::ScriptExecutionContext::minimumTimerInterval):
* dom/ScriptExecutionContext.h:
* page/DOMTimer.cpp:
(WebCore::DOMTimer::DOMTimer):
(WebCore::DOMTimer::fired):
(WebCore::DOMTimer::adjustMinimumTimerInterval):
(WebCore::DOMTimer::intervalClampedToMinimum):
* page/DOMTimer.h:
(WebCore::DOMTimer::defaultMinTimerInterval):
(WebCore::DOMTimer::setDefaultMinTimerInterval):
* page/Page.cpp:
(WebCore::Page::Page):
(WebCore::Page::setMinimumTimerInterval):
(WebCore::Page::minimumTimerInterval):
* page/Page.h:
* page/Settings.cpp:
(WebCore::Settings::setDefaultMinDOMTimerInterval):
(WebCore::Settings::defaultMinDOMTimerInterval):
(WebCore::Settings::setMinDOMTimerInterval):
(WebCore::Settings::minDOMTimerInterval):
* page/Settings.h:
* platform/Timer.h:
(WebCore::TimerBase::augmentFireInterval):
(WebCore::TimerBase::augmentRepeatInterval):
2011-02-15 Simon Fraser <simon.fraser@apple.com>
Reviewed by Beth Dakin.
......@@ -796,6 +796,7 @@ __ZN7WebCore8Settings18setFixedFontFamilyERKN3WTF12AtomicStringE
__ZN7WebCore8Settings18setMinimumFontSizeEi
__ZN7WebCore8Settings18setSerifFontFamilyERKN3WTF12AtomicStringE
__ZN7WebCore8Settings18setWebAudioEnabledEb
__ZN7WebCore8Settings19minDOMTimerIntervalEv
__ZN7WebCore8Settings19setShowDebugBordersEb
__ZN7WebCore8Settings20setCursiveFontFamilyERKN3WTF12AtomicStringE
__ZN7WebCore8Settings20setFantasyFontFamilyERKN3WTF12AtomicStringE
......@@ -825,6 +826,7 @@ __ZN7WebCore8Settings25setNeedsLeopardMailQuirksEb
__ZN7WebCore8Settings25setPrivateBrowsingEnabledEb
__ZN7WebCore8Settings25setShouldPrintBackgroundsEb
__ZN7WebCore8Settings25setUserStyleSheetLocationERKNS_4KURLE
__ZN7WebCore8Settings26defaultMinDOMTimerIntervalEv
__ZN7WebCore8Settings26setDefaultTextEncodingNameERKN3WTF6StringE
__ZN7WebCore8Settings26setNeedsSiteSpecificQuirksEb
__ZN7WebCore8Settings27setFTPDirectoryTemplatePathERKN3WTF6StringE
......@@ -834,6 +836,7 @@ __ZN7WebCore8Settings27setSpatialNavigationEnabledEb
__ZN7WebCore8Settings28setForceFTPDirectoryListingsEb
__ZN7WebCore8Settings29setAccelerated2dCanvasEnabledEb
__ZN7WebCore8Settings29setAuthorAndUserStylesEnabledEb
__ZN7WebCore8Settings29setDefaultMinDOMTimerIntervalEd
__ZN7WebCore8Settings29setWebArchiveDebugModeEnabledEb
__ZN7WebCore8Settings30setAllowFileAccessFromFileURLsEb
__ZN7WebCore8Settings31setJavaScriptCanAccessClipboardEb
......
......@@ -2243,6 +2243,14 @@ KURL Document::virtualCompleteURL(const String& url) const
return completeURL(url);
}
double Document::minimumTimerInterval() const
{
Page* p = page();
if (!p)
return ScriptExecutionContext::minimumTimerInterval();
return p->settings()->minDOMTimerInterval();
}
EventTarget* Document::errorEventTarget()
{
return domWindow();
......
......@@ -1135,6 +1135,8 @@ private:
virtual const KURL& virtualURL() const; // Same as url(), but needed for ScriptExecutionContext to implement it without a performance loss for direct calls.
virtual KURL virtualCompleteURL(const String&) const; // Same as completeURL() for the same reason as above.
virtual double minimumTimerInterval() const;
String encoding() const;
void updateTitle();
......
......@@ -30,6 +30,7 @@
#include "ActiveDOMObject.h"
#include "Blob.h"
#include "BlobURL.h"
#include "DOMTimer.h"
#include "DOMURL.h"
#include "Database.h"
#include "DatabaseTask.h"
......@@ -41,6 +42,7 @@
#include "MessagePort.h"
#include "ScriptCallStack.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#include "ThreadableBlobRegistry.h"
#include "WorkerContext.h"
#include "WorkerThread.h"
......@@ -406,6 +408,26 @@ FileThread* ScriptExecutionContext::fileThread()
}
#endif
void ScriptExecutionContext::adjustMinimumTimerInterval(double oldMinimumTimerInterval)
{
if (minimumTimerInterval() != oldMinimumTimerInterval) {
for (TimeoutMap::iterator iter = m_timeouts.begin(); iter != m_timeouts.end(); ++iter) {
DOMTimer* timer = iter->second;
timer->adjustMinimumTimerInterval(oldMinimumTimerInterval);
}
}
}
double ScriptExecutionContext::minimumTimerInterval() const
{
// The default implementation returns the DOMTimer's default
// minimum timer interval. FIXME: to make it work with dedicated
// workers, we will have to override it in the appropriate
// subclass, and provide a way to enumerate a Document's dedicated
// workers so we can update them all.
return Settings::defaultMinDOMTimerInterval();
}
ScriptExecutionContext::Task::~Task()
{
}
......
......@@ -152,6 +152,10 @@ namespace WebCore {
void stopFileThread();
#endif
// Interval is in seconds.
void adjustMinimumTimerInterval(double oldMinimumTimerInterval);
virtual double minimumTimerInterval() const;
protected:
// Explicitly override the security origin for this script context.
// Note: It is dangerous to change the security origin of a script context
......@@ -176,7 +180,8 @@ namespace WebCore {
bool m_iteratingActiveDOMObjects;
bool m_inDestructor;
HashMap<int, DOMTimer*> m_timeouts;
typedef HashMap<int, DOMTimer*> TimeoutMap;
TimeoutMap m_timeouts;
#if ENABLE(BLOB)
HashSet<String> m_publicBlobURLs;
......
......@@ -39,13 +39,14 @@ namespace WebCore {
static const int maxTimerNestingLevel = 5;
static const double oneMillisecond = 0.001;
double DOMTimer::s_minTimerInterval = 0.010; // 10 milliseconds
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 lastUsedTimeoutId = 0;
++lastUsedTimeoutId;
......@@ -58,10 +59,7 @@ DOMTimer::DOMTimer(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction>
scriptExecutionContext()->addTimeout(m_timeoutId, this);
double intervalMilliseconds = max(oneMillisecond, timeout * oneMillisecond);
if (intervalMilliseconds < s_minTimerInterval && m_nestingLevel >= maxTimerNestingLevel)
intervalMilliseconds = s_minTimerInterval;
double intervalMilliseconds = intervalClampedToMinimum(timeout, context->minimumTimerInterval());
if (singleShot)
startOneShot(intervalMilliseconds);
else
......@@ -108,10 +106,11 @@ void DOMTimer::fired()
// Simple case for non-one-shot timers.
if (isActive()) {
if (repeatInterval() && repeatInterval() < s_minTimerInterval) {
double minimumInterval = context->minimumTimerInterval();
if (repeatInterval() && repeatInterval() < minimumInterval) {
m_nestingLevel++;
if (m_nestingLevel >= maxTimerNestingLevel)
augmentRepeatInterval(s_minTimerInterval - repeatInterval());
augmentRepeatInterval(minimumInterval - repeatInterval());
}
// No access to member variables after this point, it can delete the timer.
......@@ -150,4 +149,22 @@ void DOMTimer::stop()
m_action.clear();
}
void DOMTimer::adjustMinimumTimerInterval(double oldMinimumTimerInterval)
{
if (m_nestingLevel < maxTimerNestingLevel)
return;
double previousClampedInterval = intervalClampedToMinimum(m_originalTimeout, oldMinimumTimerInterval);
double newClampedInterval = intervalClampedToMinimum(m_originalTimeout, scriptExecutionContext()->minimumTimerInterval());
augmentFireInterval(newClampedInterval - previousClampedInterval);
}
double DOMTimer::intervalClampedToMinimum(int timeout, double minimumTimerInterval) const
{
double intervalMilliseconds = max(oneMillisecond, timeout * oneMillisecond);
if (intervalMilliseconds < minimumTimerInterval && m_nestingLevel >= maxTimerNestingLevel)
intervalMilliseconds = minimumTimerInterval;
return intervalMilliseconds;
}
} // namespace WebCore
......@@ -34,7 +34,10 @@
namespace WebCore {
class Settings;
class DOMTimer : public SuspendableTimer {
friend class Settings;
public:
virtual ~DOMTimer();
// Creates a new timer owned by specified ScriptExecutionContext, starts it
......@@ -46,18 +49,27 @@ namespace WebCore {
virtual void contextDestroyed();
virtual void stop();
// The lowest allowable timer setting (in seconds, 0.001 == 1 ms).
static double minTimerInterval() { return s_minTimerInterval; }
static void setMinTimerInterval(double value) { s_minTimerInterval = value; }
// Adjust to a change in the ScriptExecutionContext's minimum timer interval.
// This allows the minimum allowable interval time to be changed in response
// to events like moving a tab to the background.
void adjustMinimumTimerInterval(double oldMinimumTimerInterval);
private:
DOMTimer(ScriptExecutionContext*, PassOwnPtr<ScheduledAction>, int timeout, bool singleShot);
virtual void fired();
double intervalClampedToMinimum(int timeout, double minimumTimerInterval) const;
// The default minimum allowable timer setting (in seconds, 0.001 == 1 ms).
// These are only modified via static methods in Settings.
static double defaultMinTimerInterval() { return s_minDefaultTimerInterval; }
static void setDefaultMinTimerInterval(double value) { s_minDefaultTimerInterval = value; }
int m_timeoutId;
int m_nestingLevel;
OwnPtr<ScheduledAction> m_action;
static double s_minTimerInterval;
int m_originalTimeout;
static double s_minDefaultTimerInterval;
};
} // namespace WebCore
......
......@@ -161,6 +161,7 @@ Page::Page(const PageClients& pageClients)
, m_customHTMLTokenizerChunkSize(-1)
, m_canStartMedia(true)
, m_viewMode(ViewModeWindowed)
, m_minimumTimerInterval(Settings::defaultMinDOMTimerInterval())
{
if (!allPages) {
allPages = new HashSet<Page*>;
......@@ -832,6 +833,21 @@ bool Page::javaScriptURLsAreAllowed() const
return m_javaScriptURLsAreAllowed;
}
void Page::setMinimumTimerInterval(double minimumTimerInterval)
{
double oldTimerInterval = m_minimumTimerInterval;
m_minimumTimerInterval = minimumTimerInterval;
for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNextWithWrap(false)) {
if (frame->document())
frame->document()->adjustMinimumTimerInterval(oldTimerInterval);
}
}
double Page::minimumTimerInterval() const
{
return m_minimumTimerInterval;
}
#if ENABLE(INPUT_SPEECH)
SpeechInput* Page::speechInput()
{
......
......@@ -91,6 +91,7 @@ namespace WebCore {
class Page {
WTF_MAKE_NONCOPYABLE(Page);
friend class Settings;
public:
static void scheduleForcedStyleRecalcForAllPages();
......@@ -297,6 +298,9 @@ namespace WebCore {
MediaCanStartListener* takeAnyMediaCanStartListener();
void setMinimumTimerInterval(double);
double minimumTimerInterval() const;
OwnPtr<Chrome> m_chrome;
OwnPtr<SelectionController> m_dragCaretController;
......@@ -385,6 +389,8 @@ namespace WebCore {
ViewMode m_viewMode;
ViewportArguments m_viewportArguments;
double m_minimumTimerInterval;
};
} // namespace WebCore
......
......@@ -434,9 +434,24 @@ void Settings::setDOMPasteAllowed(bool DOMPasteAllowed)
m_isDOMPasteAllowed = DOMPasteAllowed;
}
void Settings::setDefaultMinDOMTimerInterval(double interval)
{
DOMTimer::setDefaultMinTimerInterval(interval);
}
double Settings::defaultMinDOMTimerInterval()
{
return DOMTimer::defaultMinTimerInterval();
}
void Settings::setMinDOMTimerInterval(double interval)
{
DOMTimer::setMinTimerInterval(interval);
m_page->setMinimumTimerInterval(interval);
}
double Settings::minDOMTimerInterval()
{
return m_page->minimumTimerInterval();
}
void Settings::setUsesPageCache(bool usesPageCache)
......
......@@ -203,8 +203,12 @@ namespace WebCore {
void setDOMPasteAllowed(bool);
bool isDOMPasteAllowed() const { return m_isDOMPasteAllowed; }
static void setMinDOMTimerInterval(double); // Interval specified in seconds.
static void setDefaultMinDOMTimerInterval(double); // Interval specified in seconds.
static double defaultMinDOMTimerInterval();
void setMinDOMTimerInterval(double); // Per-page; initialized to default value.
double minDOMTimerInterval();
void setUsesPageCache(bool);
bool usesPageCache() const { return m_usesPageCache; }
......
......@@ -52,7 +52,8 @@ public:
double nextFireInterval() const;
double repeatInterval() const { return m_repeatInterval; }
void augmentRepeatInterval(double delta) { setNextFireTime(m_nextFireTime + delta); m_repeatInterval += delta; }
void augmentFireInterval(double delta) { setNextFireTime(m_nextFireTime + delta); }
void augmentRepeatInterval(double delta) { augmentFireInterval(delta); m_repeatInterval += delta; }
static void fireTimersInNestedEventLoop();
......
2011-02-15 Kenneth Russell <kbr@google.com>
Reviewed by Darin Fisher.
Allow controlling minimum DOMTimer interval on a per-page basis
https://bugs.webkit.org/show_bug.cgi?id=54312
* public/WebSettings.h:
- Added setMinimumTimerInterval.
* src/WebKit.cpp:
(WebKit::initialize):
- Added FIXME to remove setting of page's default timer interval.
* src/WebSettingsImpl.cpp:
(WebKit::WebSettingsImpl::setMinimumTimerInterval):
- Implemented new method on WebSettings.
* src/WebSettingsImpl.h:
2011-02-15 Jochen Eisinger <jochen@chromium.org>