mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 933483 - Don't fire events (and especially request animation frame events) when we're in a modal dialog. r=smaug
This commit is contained in:
parent
e9bf501722
commit
8e23aa0ed3
@ -8565,11 +8565,17 @@ FireOrClearDelayedEvents(nsTArray<nsCOMPtr<nsIDocument> >& aDocuments,
|
||||
return;
|
||||
|
||||
for (uint32_t i = 0; i < aDocuments.Length(); ++i) {
|
||||
// NB: Don't bother trying to fire delayed events on documents that were
|
||||
// closed before this event ran.
|
||||
if (!aDocuments[i]->EventHandlingSuppressed()) {
|
||||
fm->FireDelayedEvents(aDocuments[i]);
|
||||
nsCOMPtr<nsIPresShell> shell = aDocuments[i]->GetShell();
|
||||
if (shell) {
|
||||
shell->FireOrClearDelayedEvents(aFireEvents);
|
||||
// Only fire events for active documents.
|
||||
bool fire = aFireEvents &&
|
||||
aDocuments[i]->GetInnerWindow() &&
|
||||
aDocuments[i]->GetInnerWindow()->IsCurrentInnerWindow();
|
||||
shell->FireOrClearDelayedEvents(fire);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -992,16 +992,23 @@ nsFocusManager::FireDelayedEvents(nsIDocument* aDocument)
|
||||
NS_ENSURE_ARG(aDocument);
|
||||
|
||||
// fire any delayed focus and blur events in the same order that they were added
|
||||
for (uint32_t i = 0; i < mDelayedBlurFocusEvents.Length(); i++)
|
||||
{
|
||||
if (mDelayedBlurFocusEvents[i].mDocument == aDocument &&
|
||||
!aDocument->EventHandlingSuppressed()) {
|
||||
uint32_t type = mDelayedBlurFocusEvents[i].mType;
|
||||
nsCOMPtr<EventTarget> target = mDelayedBlurFocusEvents[i].mTarget;
|
||||
nsCOMPtr<nsIPresShell> presShell = mDelayedBlurFocusEvents[i].mPresShell;
|
||||
mDelayedBlurFocusEvents.RemoveElementAt(i);
|
||||
SendFocusOrBlurEvent(type, presShell, aDocument, target, 0, false);
|
||||
--i;
|
||||
for (uint32_t i = 0; i < mDelayedBlurFocusEvents.Length(); i++) {
|
||||
if (mDelayedBlurFocusEvents[i].mDocument == aDocument) {
|
||||
if (!aDocument->GetInnerWindow() ||
|
||||
!aDocument->GetInnerWindow()->IsCurrentInnerWindow()) {
|
||||
// If the document was navigated away from or is defunct, don't bother
|
||||
// firing events on it. Note the symmetry between this condition and
|
||||
// the similar one in nsDocument.cpp:FireOrClearDelayedEvents.
|
||||
mDelayedBlurFocusEvents.RemoveElementAt(i);
|
||||
--i;
|
||||
} else if (!aDocument->EventHandlingSuppressed()) {
|
||||
uint32_t type = mDelayedBlurFocusEvents[i].mType;
|
||||
nsCOMPtr<EventTarget> target = mDelayedBlurFocusEvents[i].mTarget;
|
||||
nsCOMPtr<nsIPresShell> presShell = mDelayedBlurFocusEvents[i].mPresShell;
|
||||
mDelayedBlurFocusEvents.RemoveElementAt(i);
|
||||
SendFocusOrBlurEvent(type, presShell, aDocument, target, 0, false);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1266,6 +1266,8 @@ nsGlobalWindow::~nsGlobalWindow()
|
||||
while ((w = (nsGlobalWindow *)PR_LIST_HEAD(this)) != this) {
|
||||
PR_REMOVE_AND_INIT_LINK(w);
|
||||
}
|
||||
|
||||
DropOuterWindowDocs();
|
||||
} else {
|
||||
Telemetry::Accumulate(Telemetry::INNERWINDOWS_WITH_MUTATION_LISTENERS,
|
||||
mMutationBits ? 1 : 0);
|
||||
@ -1286,9 +1288,9 @@ nsGlobalWindow::~nsGlobalWindow()
|
||||
if (outer) {
|
||||
outer->MaybeClearInnerWindow(this);
|
||||
}
|
||||
}
|
||||
|
||||
ClearDelayedEventsAndDropDocument();
|
||||
MOZ_ASSERT_IF(mDoc, !mDoc->EventHandlingSuppressed());
|
||||
}
|
||||
|
||||
// Outer windows are always supposed to call CleanUp before letting themselves
|
||||
// be destroyed. And while CleanUp generally seems to be intended to clean up
|
||||
@ -1360,12 +1362,11 @@ nsGlobalWindow::MaybeForgiveSpamCount()
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::ClearDelayedEventsAndDropDocument()
|
||||
nsGlobalWindow::DropOuterWindowDocs()
|
||||
{
|
||||
if (mDoc && mDoc->EventHandlingSuppressed()) {
|
||||
mDoc->UnsuppressEventHandlingAndFireEvents(false);
|
||||
}
|
||||
MOZ_ASSERT(IsOuterWindow());
|
||||
mDoc = nullptr;
|
||||
mSuspendedDoc = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1545,6 +1546,10 @@ nsGlobalWindow::FreeInnerObjects()
|
||||
mDocumentPrincipal = mDoc->NodePrincipal();
|
||||
mDocumentURI = mDoc->GetDocumentURI();
|
||||
mDocBaseURI = mDoc->GetDocBaseURI();
|
||||
|
||||
if (mDoc->EventHandlingSuppressed()) {
|
||||
mDoc->UnsuppressEventHandlingAndFireEvents(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove our reference to the document and the document principal.
|
||||
@ -2271,6 +2276,10 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
||||
// document.
|
||||
mDoc = aDocument;
|
||||
|
||||
// Take this opportunity to clear mSuspendedDoc. Our old inner window is now
|
||||
// responsible for unsuspending it.
|
||||
mSuspendedDoc = nullptr;
|
||||
|
||||
#ifdef DEBUG
|
||||
mLastOpenedURI = aDocument->GetDocumentURI();
|
||||
#endif
|
||||
@ -2766,7 +2775,7 @@ nsGlobalWindow::DetachFromDocShell()
|
||||
mDocBaseURI = mDoc->GetDocBaseURI();
|
||||
|
||||
// Release our document reference
|
||||
ClearDelayedEventsAndDropDocument();
|
||||
DropOuterWindowDocs();
|
||||
mFocusedNode = nullptr;
|
||||
}
|
||||
|
||||
@ -8170,6 +8179,8 @@ nsGlobalWindow::ReallyCloseWindow()
|
||||
void
|
||||
nsGlobalWindow::EnterModalState()
|
||||
{
|
||||
FORWARD_TO_OUTER_VOID(EnterModalState, ());
|
||||
|
||||
// GetScriptableTop, not GetTop, so that EnterModalState works properly with
|
||||
// <iframe mozbrowser>.
|
||||
nsGlobalWindow* topWin = GetScriptableTop();
|
||||
@ -8203,10 +8214,8 @@ nsGlobalWindow::EnterModalState()
|
||||
NS_ASSERTION(!mSuspendedDoc, "Shouldn't have mSuspendedDoc here!");
|
||||
|
||||
mSuspendedDoc = topWin->GetExtantDoc();
|
||||
if (mSuspendedDoc && mSuspendedDoc->EventHandlingSuppressed()) {
|
||||
if (mSuspendedDoc) {
|
||||
mSuspendedDoc->SuppressEventHandling();
|
||||
} else {
|
||||
mSuspendedDoc = nullptr;
|
||||
}
|
||||
}
|
||||
topWin->mModalStateDepth++;
|
||||
@ -8285,6 +8294,8 @@ private:
|
||||
void
|
||||
nsGlobalWindow::LeaveModalState()
|
||||
{
|
||||
FORWARD_TO_OUTER_VOID(LeaveModalState, ());
|
||||
|
||||
nsGlobalWindow* topWin = GetScriptableTop();
|
||||
|
||||
if (!topWin) {
|
||||
|
@ -981,7 +981,7 @@ protected:
|
||||
|
||||
// Object Management
|
||||
virtual ~nsGlobalWindow();
|
||||
void ClearDelayedEventsAndDropDocument();
|
||||
void DropOuterWindowDocs();
|
||||
void CleanUp();
|
||||
void ClearControllers();
|
||||
nsresult FinalClose();
|
||||
@ -1476,6 +1476,12 @@ protected:
|
||||
|
||||
nsAutoPtr<nsJSThingHashtable<nsPtrHashKey<nsXBLPrototypeHandler>, JSObject*> > mCachedXBLPrototypeHandlers;
|
||||
|
||||
// mSuspendedDoc is only set on outer windows. It's useful when we get matched
|
||||
// EnterModalState/LeaveModalState calls, in which case the outer window is
|
||||
// responsible for unsuspending events on the document. If we don't (for
|
||||
// example, if the outer window is closed before the LeaveModalState call),
|
||||
// then the inner window whose mDoc is our mSuspendedDoc is responsible for
|
||||
// unsuspending it.
|
||||
nsCOMPtr<nsIDocument> mSuspendedDoc;
|
||||
|
||||
nsRefPtr<mozilla::dom::indexedDB::IDBFactory> mIndexedDB;
|
||||
|
Loading…
Reference in New Issue
Block a user