Bug 1094083 - Make browser-element Handle nested alert gracefully. r=smaug

Don't delete this._windowIDDict[outerID] until the last modal prompt is
closed.

--HG--
extra : rebase_source : 22d283081532abf5fdfb7fd861127a41f238b1ea
This commit is contained in:
Kan-Ru Chen (陳侃如) 2014-11-07 10:01:14 +08:00
Родитель b964b29e92
Коммит da33fd4bd9
2 изменённых файлов: 139 добавлений и 2 удалений

Просмотреть файл

@ -379,6 +379,10 @@ BrowserElementChild.prototype = {
}
debug("Nested event loop - finish");
if (win.modalDepth == 0) {
delete this._windowIDDict[outerWindowID];
}
// If we exited the loop because the inner window changed, then bail on the
// modal prompt.
if (innerWindowID !== this._tryGetInnerWindowID(win)) {
@ -411,7 +415,6 @@ BrowserElementChild.prototype = {
}
let win = this._windowIDDict[outerID].get();
delete this._windowIDDict[outerID];
if (!win) {
debug("recvStopWaiting, but window is gone\n");

Просмотреть файл

@ -124,7 +124,7 @@ function test4() {
// test4 is a mozbrowsershowmodalprompt listener.
function test5(e) {
iframe.removeEventListener('mozbrowsershowmodalprompt', test4);
iframe.removeEventListener('mozbrowsershowmodalprompt', test5);
is(e.detail.message, 'test4');
e.preventDefault(); // cause the page to block.
@ -139,6 +139,140 @@ function test5a() {
function test5b() {
iframe.removeEventListener('mozbrowserloadend', test5b);
SimpleTest.executeSoon(test6);
}
// Test nested alerts
var promptBlockers = [];
function test6() {
iframe.addEventListener("mozbrowsershowmodalprompt", test6a);
var script = 'data:,\
this.testState = 0; \
content.alert(1); \
this.testState = 3; \
';
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
}
function test6a(e) {
iframe.removeEventListener("mozbrowsershowmodalprompt", test6a);
is(e.detail.message, '1');
e.preventDefault(); // cause the alert to block.
promptBlockers.push(e);
SimpleTest.executeSoon(test6b);
}
function test6b() {
var script = 'data:,\
if (this.testState === 0) { \
sendAsyncMessage("test-success", "1: Correct testState"); \
} \
else { \
sendAsyncMessage("test-fail", "1: Wrong testState: " + this.testState); \
}';
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
numPendingChildTests++;
waitForPendingTests(test6c);
}
function test6c() {
iframe.addEventListener("mozbrowsershowmodalprompt", test6d);
var script = 'data:,\
this.testState = 1; \
content.alert(2); \
this.testState = 2; \
';
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
}
function test6d(e) {
iframe.removeEventListener("mozbrowsershowmodalprompt", test6d);
is(e.detail.message, '2');
e.preventDefault(); // cause the alert to block.
promptBlockers.push(e);
SimpleTest.executeSoon(test6e);
}
function test6e() {
var script = 'data:,\
if (this.testState === 1) { \
sendAsyncMessage("test-success", "2: Correct testState"); \
} \
else { \
sendAsyncMessage("test-fail", "2: Wrong testState: " + this.testState); \
}';
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
numPendingChildTests++;
waitForPendingTests(test6f);
}
function test6f() {
var e = promptBlockers.pop();
// Now unblock the iframe and check that the script completed.
e.detail.unblock();
var script2 = 'data:,\
if (this.testState === 2) { \
sendAsyncMessage("test-success", "3: Correct testState"); \
} \
else { \
sendAsyncMessage("test-try-again", "3: Wrong testState (for now): " + this.testState); \
}';
// Urgh. e.unblock() didn't necessarily unblock us immediately, so we have
// to spin and wait.
function onTryAgain() {
SimpleTest.executeSoon(function() {
//dump('onTryAgain\n');
mm.loadFrameScript(script2, /* allowDelayedLoad = */ false);
});
}
mm.addMessageListener('test-try-again', onTryAgain);
numPendingChildTests++;
onTryAgain();
waitForPendingTests(test6g);
}
function test6g() {
var e = promptBlockers.pop();
// Now unblock the iframe and check that the script completed.
e.detail.unblock();
var script2 = 'data:,\
if (this.testState === 3) { \
sendAsyncMessage("test-success", "4: Correct testState"); \
} \
else { \
sendAsyncMessage("test-try-again", "4: Wrong testState (for now): " + this.testState); \
}';
// Urgh. e.unblock() didn't necessarily unblock us immediately, so we have
// to spin and wait.
function onTryAgain() {
SimpleTest.executeSoon(function() {
//dump('onTryAgain\n');
mm.loadFrameScript(script2, /* allowDelayedLoad = */ false);
});
}
mm.addMessageListener('test-try-again', onTryAgain);
numPendingChildTests++;
onTryAgain();
waitForPendingTests(test6h);
}
function test6h() {
SimpleTest.finish();
}