mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 20:49:27 +00:00
Bug 492560: Prevent modal dialogs from making the slow-script dialog coming up. r/sr=mrbkap
This commit is contained in:
parent
51c82bccc0
commit
12efda0ab2
@ -4453,7 +4453,9 @@ nsGlobalWindow::Print()
|
||||
printSettingsService->GetNewPrintSettings(getter_AddRefs(printSettings));
|
||||
}
|
||||
|
||||
EnterModalState();
|
||||
webBrowserPrint->Print(printSettings, nsnull);
|
||||
LeaveModalState();
|
||||
|
||||
PRBool savePrintSettings =
|
||||
nsContentUtils::GetBoolPref("print.save_print_settings", PR_FALSE);
|
||||
@ -5640,6 +5642,13 @@ nsGlobalWindow::EnterModalState()
|
||||
}
|
||||
}
|
||||
topWin->mModalStateDepth++;
|
||||
|
||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
||||
|
||||
nsIScriptContext *scx;
|
||||
if (cx && (scx = GetScriptContextFromJSContext(cx))) {
|
||||
scx->EnterModalState();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
@ -5743,6 +5752,13 @@ nsGlobalWindow::LeaveModalState()
|
||||
mSuspendedDoc = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
||||
|
||||
nsIScriptContext *scx;
|
||||
if (cx && (scx = GetScriptContextFromJSContext(cx))) {
|
||||
scx->LeaveModalState();
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -56,10 +56,10 @@ class nsScriptObjectHolder;
|
||||
|
||||
typedef void (*nsScriptTerminationFunc)(nsISupports* aRef);
|
||||
|
||||
// 87482b5e-e019-4df5-9bc2-b2a51b1f2d28
|
||||
#define NS_ISCRIPTCONTEXT_IID \
|
||||
{ /* {09316a0e-8d05-4d26-9efd-8f907a7c79d2} */ \
|
||||
0x09316a0e, 0x8d05, 0x4d26, \
|
||||
{ 0x9e, 0xfd, 0x8f, 0x90, 0x7a, 0x7c, 0x79, 0xd2 } }
|
||||
{ 0x87482b5e, 0xe019, 0x4df5, \
|
||||
{ 0x9b, 0xc2, 0xb2, 0xa5, 0x1b, 0x1f, 0x2d, 0x28 } }
|
||||
|
||||
/* This MUST match JSVERSION_DEFAULT. This version stuff if we don't
|
||||
know what language we have is a little silly... */
|
||||
@ -456,6 +456,9 @@ public:
|
||||
*/
|
||||
virtual nsresult DropScriptObject(void *object) = 0;
|
||||
virtual nsresult HoldScriptObject(void *object) = 0;
|
||||
|
||||
virtual void EnterModalState() = 0;
|
||||
virtual void LeaveModalState() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContext, NS_ISCRIPTCONTEXT_IID)
|
||||
|
@ -906,11 +906,13 @@ nsJSContext::DOMOperationCallback(JSContext *cx)
|
||||
// ScriptEvaluated to be called, and clearing our operation callback time.
|
||||
// See bug 302333.
|
||||
PRTime callbackTime = ctx->mOperationCallbackTime;
|
||||
PRTime modalStateTime = ctx->mModalStateTime;
|
||||
|
||||
MaybeGC(cx);
|
||||
|
||||
// Now restore the callback time and count, in case they got reset.
|
||||
ctx->mOperationCallbackTime = callbackTime;
|
||||
ctx->mModalStateTime = modalStateTime;
|
||||
|
||||
// Check to see if we are running OOM
|
||||
nsCOMPtr<nsIMemory> mem;
|
||||
@ -965,15 +967,20 @@ nsJSContext::DOMOperationCallback(JSContext *cx)
|
||||
|
||||
PRTime now = PR_Now();
|
||||
|
||||
if (LL_IS_ZERO(callbackTime)) {
|
||||
if (callbackTime == 0) {
|
||||
// Initialize mOperationCallbackTime to start timing how long the
|
||||
// script has run
|
||||
ctx->mOperationCallbackTime = now;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PRTime duration;
|
||||
LL_SUB(duration, now, callbackTime);
|
||||
if (ctx->mModalStateDepth) {
|
||||
// We're waiting on a modal dialog, nothing more to do here.
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PRTime duration = now - callbackTime;
|
||||
|
||||
// Check the amount of time this script has been running, or if the
|
||||
// dialog is disabled.
|
||||
@ -1153,6 +1160,46 @@ nsJSContext::DOMOperationCallback(JSContext *cx)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nsJSContext::EnterModalState()
|
||||
{
|
||||
if (!mModalStateDepth) {
|
||||
mModalStateTime = mOperationCallbackTime ? PR_Now() : 0;
|
||||
}
|
||||
++mModalStateDepth;
|
||||
}
|
||||
|
||||
void
|
||||
nsJSContext::LeaveModalState()
|
||||
{
|
||||
if (!mModalStateDepth) {
|
||||
NS_ERROR("Uh, mismatched LeaveModalState() call!");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
--mModalStateDepth;
|
||||
|
||||
// If we're still in a modal dialog, or mOperationCallbackTime is still
|
||||
// uninitialized, do nothing.
|
||||
if (mModalStateDepth || !mOperationCallbackTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If mOperationCallbackTime was set when we entered the first dialog
|
||||
// (and mModalStateTime is thus non-zero), adjust mOperationCallbackTime
|
||||
// to account for time spent in the dialog.
|
||||
// If mOperationCallbackTime got set while the modal dialog was open,
|
||||
// simply set mOperationCallbackTime to the closing time of the dialog so
|
||||
// that we never adjust mOperationCallbackTime to be in the future.
|
||||
if (mModalStateTime) {
|
||||
mOperationCallbackTime += PR_Now() - mModalStateTime;
|
||||
}
|
||||
else {
|
||||
mOperationCallbackTime = PR_Now();
|
||||
}
|
||||
}
|
||||
|
||||
#define JS_OPTIONS_DOT_STR "javascript.options."
|
||||
|
||||
static const char js_options_dot_str[] = JS_OPTIONS_DOT_STR;
|
||||
@ -1275,7 +1322,9 @@ nsJSContext::nsJSContext(JSRuntime *aRuntime) : mGCOnDestruction(PR_TRUE)
|
||||
mNumEvaluations = 0;
|
||||
mTerminations = nsnull;
|
||||
mScriptsEnabled = PR_TRUE;
|
||||
mOperationCallbackTime = LL_ZERO;
|
||||
mOperationCallbackTime = 0;
|
||||
mModalStateTime = 0;
|
||||
mModalStateDepth = 0;
|
||||
mProcessingScriptTag = PR_FALSE;
|
||||
}
|
||||
|
||||
@ -3363,7 +3412,8 @@ nsJSContext::ScriptEvaluated(PRBool aTerminated)
|
||||
}
|
||||
|
||||
if (aTerminated) {
|
||||
mOperationCallbackTime = LL_ZERO;
|
||||
mOperationCallbackTime = 0;
|
||||
mModalStateTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,6 +165,9 @@ public:
|
||||
virtual nsresult DropScriptObject(void *object);
|
||||
virtual nsresult HoldScriptObject(void *object);
|
||||
|
||||
virtual void EnterModalState();
|
||||
virtual void LeaveModalState();
|
||||
|
||||
NS_DECL_NSIXPCSCRIPTNOTIFY
|
||||
|
||||
static void LoadStart();
|
||||
@ -288,6 +291,9 @@ private:
|
||||
PRUint32 mDefaultJSOptions;
|
||||
PRTime mOperationCallbackTime;
|
||||
|
||||
PRTime mModalStateTime;
|
||||
PRUint32 mModalStateDepth;
|
||||
|
||||
// mGlobalWrapperRef is used only to hold a strong reference to the
|
||||
// global object wrapper while the nsJSContext is alive. This cuts
|
||||
// down on the number of rooting and unrooting calls XPConnect has
|
||||
|
Loading…
x
Reference in New Issue
Block a user