Using tab-modal prompts

Prior to Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1), prompts (that is, alerts and other modal prompts) were window modal. That is, when an alert occurred, it blocked the user interface on all tabs in the window until the user dismissed the prompt.

old-style.png
Window-modal alert.

Gecko 2.0 introduces tab modal prompts, which only block the tab with which they're associated. Only the window.alert() method gets this by default; you get this by default.

new-way.png
Tab-modal alert.

Disabling tab-modal prompts

You can disable tab-modal prompts and get back window-modal prompts by setting the prompts.tab_modal.enabled preference to false.

Using tab-modal prompts from chrome code

Currently, nsIPrompt defaults to using window-modal prompts. You can force a prompt to be tab-modal using code like this:

var theWindow = gBrowser.contentWindow;
let prompt = Components.classes["@mozilla.org/prompter;1"]
             .getService(Components.interfaces.nsIPromptFactory)
             .getPrompt(theWindow, Components.interfaces.nsIPrompt);
let bag = prompt.QueryInterface(Components.interfaces.nsIWritablePropertyBag2);
bag.setPropertyAsBool("allowTabModal", true);

The var "theWindow" is a reference to the DOM window. Even if you set it to the browser window ("var theWindow = window") the modal alert will be shown in the current tab. From then on, you can use the nsIPrompt object, prompt, as usual. For example:

var factory = Components.classes["@mozilla.org/prompter;1"]
    .getService(Components.interfaces.nsIPromptFactory);
var prompt = factory.getPrompt(gBrowser.contentWindow, Components.interfaces.nsIPrompt);
var bag = prompt.QueryInterface(Components.interfaces.nsIWritablePropertyBag2);
bag.setPropertyAsBool("allowTabModal", true);
var promptArgs = ["Devmo Alert", "OMG! An alert!"];
prompt.alert.apply(null, promptArgs);

nsIPrompt will automatically fall back to window-modal prompts when necessary (such as in situations in which tab-modal prompts aren't supported, or for prompts displayed outside the context of a tab).le

To use other forms of the prompts of nsIPromptService interface see the Example Code. Then apply it, like in the example below, here we apply the prompt with a checkbox:

var window = gBrowser.contentWindow;
var promptfact = Components.classes['@mozilla.org/prompter;1'].getService(Components.interfaces.nsIPromptFactory);
var prompt = promptfact.getPrompt(window, Components.interfaces.nsIPrompt);
var promptbag = prompt.QueryInterface(Components.interfaces.nsIWritablePropertyBag2);
promptbag.setPropertyAsBool('allowTabModal', true);
var check = {value: false}; //initial state of checkbox, however if no text is supplied the checkbox is not shown
var input = {value: 'pre filled value'};
var ok = prompt.prompt.apply(null, ['Title - but not shown in tab modal', 'Text goes here', input, 'Check text, if no text, checkbox is not shown', check]);
//this here is just an alert, showing the values of the prompt
prompt.alert.apply(null, ['Title Not Shown In Modal', 'User Clicked OK: ' + ok + '\n' + 'Checked: ' + check.value + '\nInput Value: ' + input.value]);

Note: Because the prompts are shown in a tab, if the tab is closed while the prompt is open it will throw an exception.

/*
Exception: prompt aborted by user
undefined:425
*/

 

/*
Exception: prompt aborted by user
undefined:425
*/
/*
Exception: prompt aborted by user
undefined:425
*/

Document Tags and Contributors

 Contributors to this page: teoli, Noitidart, Sheppy
 Last updated by: Noitidart,