Bug 638352 - tab-modal dialogs can get into bad focus state and key events can bleed through tabs. r=gavin

This commit is contained in:
Justin Dolske 2011-04-19 14:18:17 -07:00
parent 77bd0e5388
commit 62611b3e52
3 changed files with 50 additions and 34 deletions

View File

@ -357,15 +357,10 @@
let promptBox = {
appendPrompt : function(args, onCloseCallback) {
let count = browser.getAttribute("tabmodalPromptShowing");
if (count)
count = parseInt(count) + 1;
else
count = 1;
browser.setAttribute("tabmodalPromptShowing", count);
let newPrompt = document.createElementNS(XUL_NS, "tabmodalprompt");
stack.appendChild(newPrompt);
browser.setAttribute("tabmodalPromptShowing", true);
newPrompt.clientTop; // style flush to assure binding is attached
let tab = self._getTabForContentWindow(browser.contentWindow);
@ -374,21 +369,22 @@
},
removePrompt : function(aPrompt) {
let count = parseInt(browser.getAttribute("tabmodalPromptShowing"));
count--;
if (count)
browser.setAttribute("tabmodalPromptShowing", count);
else
browser.removeAttribute("tabmodalPromptShowing");
stack.removeChild(aPrompt);
let prompts = this.listPrompts();
if (prompts.length) {
let prompt = prompts[prompts.length - 1];
prompt.Dialog.setDefaultFocus();
} else {
browser.removeAttribute("tabmodalPromptShowing");
browser.focus();
}
},
listPrompts : function(aPrompt) {
let prompts = [];
let els = stack.getElementsByTagNameNS(XUL_NS, "tabmodalprompt");
// NodeList --> real JS array
for (let i = 0; i < els.length; i++)
prompts.push(els[i]);
let prompts = Array.slice(els);
return prompts;
},
};
@ -952,6 +948,16 @@
// Adjust focus
do {
// If there's a tabmodal prompt showing, focus it.
if (newBrowser.hasAttribute("tabmodalPromptShowing")) {
let XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let prompts = newBrowser.parentNode.getElementsByTagNameNS(XUL_NS, "tabmodalprompt");
let prompt = prompts[prompts.length - 1];
prompt.Dialog.setDefaultFocus();
break;
}
// Focus the location bar if it was previously focused for that tab.
// In full screen mode, only bother making the location bar visible
// if the tab is a blank one.

View File

@ -190,18 +190,7 @@ CommonDialog.prototype = {
button.setAttribute("default", "true");
// Set default focus / selection.
if (!this.hasInputField) {
let isOSX = ("nsILocalFileMac" in Components.interfaces);
if (isOSX)
this.ui.infoBody.focus();
else
button.focus();
} else {
if (this.args.promptType == "promptPassword")
this.ui.password1Textbox.select();
else
this.ui.loginTextbox.select();
}
this.setDefaultFocus(true);
if (this.args.enableDelay) {
this.setButtonsEnabledState(false);
@ -310,6 +299,33 @@ CommonDialog.prototype = {
this.setButtonsEnabledState(true);
},
setDefaultFocus : function(isInitialLoad) {
let b = (this.args.defaultButtonNum || 0);
let button = this.ui["button" + b];
if (!this.hasInputField) {
let isOSX = ("nsILocalFileMac" in Components.interfaces);
if (isOSX)
this.ui.infoBody.focus();
else
button.focus();
} else {
// When the prompt is initialized, focus and select the textbox
// contents. Afterwards, only focus the textbox.
if (this.args.promptType == "promptPassword") {
if (isInitialLoad)
this.ui.password1Textbox.select();
else
this.ui.password1Textbox.focus();
} else {
if (isInitialLoad)
this.ui.loginTextbox.select();
else
this.ui.loginTextbox.focus();
}
}
},
onCheckbox : function() {
this.args.checked = this.ui.checkbox.checked;
},

View File

@ -438,12 +438,6 @@ function openTabPrompt(domWin, tabPrompt, args) {
winUtils.leaveModalStateWithWindow(callerWin);
PromptUtils.fireDialogEvent(domWin, "DOMModalDialogClosed");
// Restore focus to the previously focused element within tab.
let fm = Cc["@mozilla.org/focus-manager;1"].
getService(Ci.nsIFocusManager);
let e = fm.getFocusedElementForWindow(domWin.top, false, {});
fm.setFocus(e, fm.FLAG_NOSCROLL);
}
let newPrompt;