зеркало из https://github.com/mozilla/pjs.git
Bug 675121. Unregister animation frame callbacks from the refresh driver while we have event handling suppressed. r=smaug,roc
This commit is contained in:
Родитель
027ba1376c
Коммит
4793353c33
|
@ -1331,6 +1331,10 @@ public:
|
|||
|
||||
PRUint32 EventHandlingSuppressed() const { return mEventsSuppressed; }
|
||||
|
||||
bool IsEventHandlingEnabled() {
|
||||
return !EventHandlingSuppressed() && mScriptGlobalObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the number of external scripts being evaluated.
|
||||
*/
|
||||
|
|
|
@ -3196,9 +3196,7 @@ nsDocument::doCreateShell(nsPresContext* aContext,
|
|||
|
||||
mExternalResourceMap.ShowViewers();
|
||||
|
||||
if (mScriptGlobalObject) {
|
||||
RescheduleAnimationFrameNotifications();
|
||||
}
|
||||
MaybeRescheduleAnimationFrameNotifications();
|
||||
|
||||
shell.swap(*aInstancePtrResult);
|
||||
|
||||
|
@ -3206,8 +3204,13 @@ nsDocument::doCreateShell(nsPresContext* aContext,
|
|||
}
|
||||
|
||||
void
|
||||
nsDocument::RescheduleAnimationFrameNotifications()
|
||||
nsDocument::MaybeRescheduleAnimationFrameNotifications()
|
||||
{
|
||||
if (!mPresShell || !IsEventHandlingEnabled()) {
|
||||
// bail out for now, until one of those conditions changes
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefreshDriver* rd = mPresShell->GetPresContext()->RefreshDriver();
|
||||
if (mHavePendingPaint) {
|
||||
rd->ScheduleBeforePaintEvent(this);
|
||||
|
@ -3228,7 +3231,7 @@ void
|
|||
nsDocument::DeleteShell()
|
||||
{
|
||||
mExternalResourceMap.HideViewers();
|
||||
if (mScriptGlobalObject) {
|
||||
if (IsEventHandlingEnabled()) {
|
||||
RevokeAnimationFrameNotifications();
|
||||
}
|
||||
mPresShell = nsnull;
|
||||
|
@ -3776,7 +3779,7 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
|||
// our layout history state now.
|
||||
mLayoutHistoryState = GetLayoutHistoryState();
|
||||
|
||||
if (mPresShell) {
|
||||
if (mPresShell && !EventHandlingSuppressed()) {
|
||||
RevokeAnimationFrameNotifications();
|
||||
}
|
||||
|
||||
|
@ -3837,9 +3840,7 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
|||
}
|
||||
}
|
||||
|
||||
if (mPresShell) {
|
||||
RescheduleAnimationFrameNotifications();
|
||||
}
|
||||
MaybeRescheduleAnimationFrameNotifications();
|
||||
}
|
||||
|
||||
// Remember the pointer to our window (or lack there of), to avoid
|
||||
|
@ -7648,6 +7649,10 @@ SuppressEventHandlingInDocument(nsIDocument* aDocument, void* aData)
|
|||
void
|
||||
nsDocument::SuppressEventHandling(PRUint32 aIncrease)
|
||||
{
|
||||
if (mEventsSuppressed == 0 && aIncrease != 0 && mPresShell &&
|
||||
mScriptGlobalObject) {
|
||||
RevokeAnimationFrameNotifications();
|
||||
}
|
||||
mEventsSuppressed += aIncrease;
|
||||
EnumerateSubDocuments(SuppressEventHandlingInDocument, &aIncrease);
|
||||
}
|
||||
|
@ -7807,13 +7812,8 @@ GetAndUnsuppressSubDocuments(nsIDocument* aDocument, void* aData)
|
|||
void
|
||||
nsDocument::UnsuppressEventHandlingAndFireEvents(PRBool aFireEvents)
|
||||
{
|
||||
if (mEventsSuppressed > 0) {
|
||||
--mEventsSuppressed;
|
||||
}
|
||||
|
||||
nsTArray<nsCOMPtr<nsIDocument> > documents;
|
||||
documents.AppendElement(this);
|
||||
EnumerateSubDocuments(GetAndUnsuppressSubDocuments, &documents);
|
||||
GetAndUnsuppressSubDocuments(this, &documents);
|
||||
|
||||
if (aFireEvents) {
|
||||
NS_DispatchToCurrentThread(new nsDelayedEventDispatcher(documents));
|
||||
|
@ -8042,7 +8042,7 @@ nsIDocument::ScheduleBeforePaintEvent(nsIAnimationFrameListener* aListener)
|
|||
if (aListener) {
|
||||
PRBool alreadyRegistered = !mAnimationFrameListeners.IsEmpty();
|
||||
if (mAnimationFrameListeners.AppendElement(aListener) &&
|
||||
!alreadyRegistered && mPresShell) {
|
||||
!alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
|
||||
mPresShell->GetPresContext()->RefreshDriver()->
|
||||
ScheduleAnimationFrameListeners(this);
|
||||
}
|
||||
|
@ -8056,6 +8056,7 @@ nsIDocument::ScheduleBeforePaintEvent(nsIAnimationFrameListener* aListener)
|
|||
// event will fire, or we'll quietly go away at some point.
|
||||
mHavePendingPaint =
|
||||
!mPresShell ||
|
||||
!IsEventHandlingEnabled() ||
|
||||
mPresShell->GetPresContext()->RefreshDriver()->
|
||||
ScheduleBeforePaintEvent(this);
|
||||
}
|
||||
|
|
|
@ -865,7 +865,10 @@ public:
|
|||
|
||||
virtual void UnsuppressEventHandlingAndFireEvents(PRBool aFireEvents);
|
||||
|
||||
void DecreaseEventSuppression() { --mEventsSuppressed; }
|
||||
void DecreaseEventSuppression() {
|
||||
--mEventsSuppressed;
|
||||
MaybeRescheduleAnimationFrameNotifications();
|
||||
}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDocument,
|
||||
nsIDocument)
|
||||
|
@ -1149,8 +1152,9 @@ private:
|
|||
|
||||
// Revoke any pending notifications due to mozRequestAnimationFrame calls
|
||||
void RevokeAnimationFrameNotifications();
|
||||
// Reschedule any notifications we need to handle mozRequestAnimationFrame
|
||||
void RescheduleAnimationFrameNotifications();
|
||||
// Reschedule any notifications we need to handle
|
||||
// mozRequestAnimationFrame, if it's OK to do so.
|
||||
void MaybeRescheduleAnimationFrameNotifications();
|
||||
|
||||
// These are not implemented and not supported.
|
||||
nsDocument(const nsDocument& aOther);
|
||||
|
|
|
@ -501,6 +501,8 @@ _TEST_FILES2 = \
|
|||
delayedServerEvents.sjs \
|
||||
test_bug664916.html \
|
||||
test_bug666604.html \
|
||||
test_bug675121.html \
|
||||
file_bug675121.sjs \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
var timer;
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
response.write("Responded");
|
||||
response.processAsync();
|
||||
timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(Components.interfaces.nsITimer);
|
||||
timer.initWithCallback(function() {
|
||||
response.finish();
|
||||
// 50ms certainly be enough for one refresh driver firing to happen!
|
||||
}, 50, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=675121
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 675121</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=675121">Mozilla Bug 675121</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 675121 **/
|
||||
var callbackFired = false;
|
||||
var xhrInProgress = false;
|
||||
function f() {
|
||||
callbackFired = true;
|
||||
if (!xhrInProgress) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
window.mozRequestAnimationFrame(f);
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "file_bug675121.sjs", false);
|
||||
xhrInProgress = true;
|
||||
xhr.send();
|
||||
xhrInProgress = false;
|
||||
is(xhr.responseText, "Responded", "Should have a response by now");
|
||||
is(callbackFired, false, "Callback should not fire during sync XHR");
|
||||
|
||||
if (!callbackFired) {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче