Bug 332195 - part 2: allow the user to control this behaviour with a checkbox, r=mconley

--HG--
extra : commitid : 7jvP5BNMLUp
extra : rebase_source : 59b5789802d1a46f46d6bd3c04d35633c8cc7132
This commit is contained in:
Gijs Kruitbosch 2015-10-13 11:06:01 +01:00
parent b331b9bc8d
commit 9bdc4d9b9d
6 changed files with 67 additions and 6 deletions

View File

@ -8181,6 +8181,14 @@ function TabModalPromptBox(browser) {
}
TabModalPromptBox.prototype = {
_promptCloseCallback(onCloseCallback, principalToAllowFocusFor, allowFocusCheckbox, ...args) {
if (principalToAllowFocusFor && allowFocusCheckbox.checked) {
Services.perms.addFromPrincipal(principalToAllowFocusFor, "focus-tab-by-prompt",
Services.perms.ALLOW_ACTION);
}
onCloseCallback.apply(this, args);
},
appendPrompt(args, onCloseCallback) {
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let newPrompt = document.createElementNS(XUL_NS, "tabmodalprompt");
@ -8190,8 +8198,26 @@ TabModalPromptBox.prototype = {
newPrompt.clientTop; // style flush to assure binding is attached
let principalToAllowFocusFor = this._allowTabFocusByPromptPrincipal;
delete this._allowTabFocusByPromptPrincipal;
let allowFocusCheckbox; // Define outside the if block so we can bind it into the callback.
if (principalToAllowFocusFor) {
let allowFocusRow = document.createElementNS(XUL_NS, "row");
allowFocusCheckbox = document.createElementNS(XUL_NS, "checkbox");
let spacer = document.createElementNS(XUL_NS, "spacer");
allowFocusRow.appendChild(spacer);
let label = gBrowser.mStringBundle.getFormattedString("tabs.allowTabFocusByPromptForSite",
[principalToAllowFocusFor.URI.host]);
allowFocusCheckbox.setAttribute("label", label);
allowFocusRow.appendChild(allowFocusCheckbox);
newPrompt.appendChild(allowFocusRow);
}
let tab = gBrowser.getTabForBrowser(browser);
newPrompt.init(args, tab, onCloseCallback);
let closeCB = this._promptCloseCallback.bind(null, onCloseCallback, principalToAllowFocusFor,
allowFocusCheckbox);
newPrompt.init(args, tab, closeCB);
return newPrompt;
},
@ -8216,6 +8242,10 @@ TabModalPromptBox.prototype = {
return Array.from(els);
},
onNextPromptShowAllowFocusCheckboxFor(principal) {
this._allowTabFocusByPromptPrincipal = principal;
},
get browser() {
let browser = this._weakBrowserRef.get();
if (!browser) {

View File

@ -4348,11 +4348,35 @@
if (event.detail && event.detail.tabPrompt &&
Services.prefs.getBoolPref("browser.tabs.dontfocusfordialogs")) {
tabForEvent.setAttribute("attention", "true");
} else {
// bring tab to the front:
this.selectedTab = tabForEvent;
let docPrincipal = targetIsWindow ? event.target.document.nodePrincipal : null;
// At least one of these should/will be non-null:
let promptPrincipal = event.detail.promptPrincipal || docPrincipal ||
tabForEvent.linkedBrowser.contentPrincipal;
// For null principals, we bail immediately and don't show the checkbox:
if (!promptPrincipal || promptPrincipal.isNullPrincipal) {
tabForEvent.setAttribute("attention", "true");
return;
}
// For non-system/expanded principals, we bail and show the checkbox
if (promptPrincipal.URI &&
!Services.scriptSecurityManager.isSystemPrincipal(promptPrincipal)) {
let permission = Services.perms.testPermissionFromPrincipal(promptPrincipal,
"focus-tab-by-prompt");
if (permission != Services.perms.ALLOW_ACTION) {
// Tell the prompt box we want to show the user a checkbox:
let tabPrompt = this.getTabModalPromptBox(tabForEvent.linkedBrowser);
tabPrompt.onNextPromptShowAllowFocusCheckboxFor(promptPrincipal);
tabForEvent.setAttribute("attention", "true");
return;
}
}
// ... so system and expanded principals, as well as permitted "normal"
// URI-based principals, always get to steal focus for the tab when prompting.
}
// if prefs/permissions/origins so dictate, bring tab to the front:
this.selectedTab = tabForEvent;
]]>
</handler>
<handler event="DOMTitleChanged">

View File

@ -42,3 +42,7 @@ tabs.muteAudio.tooltip=Mute tab (%S)
tabs.unmuteAudio.tooltip=Unmute tab (%S)
tabs.muteAudio.background.tooltip=Mute tab
tabs.unmuteAudio.background.tooltip=Unmute tab
# LOCALIZATION NOTE (tabs.allowTabFocusByPromptForSite):
# %S is the hostname of the site where dialogs are allowed to switch tabs
tabs.allowTabFocusByPromptForSite=Allow dialogs from %S to take you to their tab

View File

@ -63,7 +63,7 @@ var RemotePrompt = {
});
try {
let eventDetail = {tabPrompt: true};
let eventDetail = {tabPrompt: true, promptPrincipal: args.promptPrincipal};
PromptUtils.fireDialogEvent(window, "DOMWillOpenModalDialog", browser, eventDetail);
args.promptActive = true;

View File

@ -56,6 +56,8 @@
<spacer/>
<checkbox anonid="checkbox"/>
</row>
<xbl:children includes="row"/>
</rows>
</grid>
<xbl:children/>

View File

@ -485,6 +485,7 @@ function openRemotePrompt(domWin, args, tabPrompt) {
let topPrincipal = domWin.top.document.nodePrincipal;
let promptPrincipal = domWin.document.nodePrincipal;
args.promptPrincipal = promptPrincipal;
args.showAlertOrigin = topPrincipal.equals(promptPrincipal);
args._remoteId = id;