зеркало из https://github.com/mozilla/gecko-dev.git
Bug 841312 - Replace the scripted closing unblocker termination function with an runnable. r=bz
The main idea behind this thing seems to be that we don't want script to quickly close the window before the user has time to read the notification. Given the fuzziness of the constraint here, I think we can (and maybe even should) unblock a little bit later in the event loop, rather than immediately after the script terminates. Note that, due to modal dialogs and their event loop spinning shenanigans, we want to do this only when the stack frame is popped.
This commit is contained in:
Родитель
78c5ff8572
Коммит
a46b3fe9f2
|
@ -9726,15 +9726,25 @@ nsGlobalWindow::GetParentInternal()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsGlobalWindow::CloseBlockScriptTerminationFunc(nsISupports *aRef)
|
||||
nsGlobalWindow::UnblockScriptedClosing()
|
||||
{
|
||||
nsGlobalWindow* pwin = static_cast<nsGlobalWindow*>
|
||||
(static_cast<nsPIDOMWindow*>(aRef));
|
||||
pwin->mBlockScriptedClosingFlag = false;
|
||||
mBlockScriptedClosingFlag = false;
|
||||
}
|
||||
|
||||
class AutoUnblockScriptClosing
|
||||
{
|
||||
private:
|
||||
nsRefPtr<nsGlobalWindow> mWin;
|
||||
public:
|
||||
AutoUnblockScriptClosing(nsGlobalWindow *aWin) : mWin(aWin) {};
|
||||
~AutoUnblockScriptClosing()
|
||||
{
|
||||
void (nsGlobalWindow::*run)() = &nsGlobalWindow::UnblockScriptedClosing;
|
||||
NS_DispatchToCurrentThread(NS_NewRunnableMethod(mWin, run));
|
||||
};
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
||||
const nsAString& aOptions, bool aDialog,
|
||||
|
@ -9764,6 +9774,8 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
|||
NS_PRECONDITION(!aJSCallerContext || !aCalledNoScript,
|
||||
"Shouldn't have caller context when called noscript");
|
||||
|
||||
mozilla::Maybe<AutoUnblockScriptClosing> closeUnblocker;
|
||||
|
||||
// Calls to window.open from script should navigate.
|
||||
MOZ_ASSERT(aCalledNoScript || aNavigate);
|
||||
|
||||
|
@ -9825,8 +9837,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
|||
// so that whatever popup blocker UI the app has will be visible.
|
||||
if (mContext == GetScriptContextFromJSContext(aJSCallerContext)) {
|
||||
mBlockScriptedClosingFlag = true;
|
||||
mContext->SetTerminationFunction(CloseBlockScriptTerminationFunc,
|
||||
this);
|
||||
closeUnblocker.construct(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -580,11 +580,12 @@ public:
|
|||
nsresult Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const PRUnichar* aData);
|
||||
|
||||
void UnblockScriptedClosing();
|
||||
|
||||
static void Init();
|
||||
static void ShutDown();
|
||||
static void CleanupCachedXBLHandlers(nsGlobalWindow* aWindow);
|
||||
static bool IsCallerChrome();
|
||||
static void CloseBlockScriptTerminationFunc(nsISupports *aRef);
|
||||
|
||||
static void RunPendingTimeoutsRecursive(nsGlobalWindow *aTopWindow,
|
||||
nsGlobalWindow *aWindow);
|
||||
|
|
Загрузка…
Ссылка в новой задаче