Using tab-modal prompts

  • Revision slug: Using_tab-modal_prompts
  • Revision title: Using tab-modal prompts
  • Revision id: 329725
  • Created:
  • Creator: Noitidart
  • Is current revision? No
  • Comment

Revision Content

{{ gecko_minversion_header("2.0") }}

Prior to Gecko 2.0 {{ geckoRelease("2.0") }}, 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 {{ domxref("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, {{ interface("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 {{ interface("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);

{{ interface("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 {{ interface("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]);

Revision Source

<p>{{ gecko_minversion_header("2.0") }}</p>
<p>Prior to Gecko 2.0 {{ geckoRelease("2.0") }}, prompts (that is, alerts and other modal prompts) were <strong>window modal</strong>.&nbsp;That is, when an alert occurred, it blocked the user interface on all tabs in the window until the user dismissed the prompt.</p>
<table border="0" cellpadding="1" cellspacing="1">
  <tbody>
    <tr>
      <td align="center"><img alt="old-style.png" class="internal default" src="/@api/deki/files/4954/=old-style.png" /></td>
    </tr>
    <tr>
      <td align="center">Window-modal alert.</td>
    </tr>
  </tbody>
</table>
<p>Gecko 2.0 introduces <strong>tab modal</strong> prompts, which only block the tab with which they're associated. Only the {{ domxref("window.alert()") }} method gets this by default; you get this by default.</p>
<table border="0" cellpadding="1" cellspacing="1">
  <tbody>
    <tr>
      <td align="center"><img alt="new-way.png" class="internal default" src="/@api/deki/files/4955/=new-way.png" /></td>
    </tr>
    <tr>
      <td align="center">Tab-modal alert.</td>
    </tr>
  </tbody>
</table>
<h2 id="Disabling_tab-modal_prompts">Disabling tab-modal prompts</h2>
<p>You can disable tab-modal prompts and get back window-modal prompts by setting the <code>prompts.tab_modal.enabled</code> preference to <code>false</code>.</p>
<h2 id="Using_tab-modal_prompts_from_chrome_code">Using tab-modal prompts from chrome code</h2>
<p>Currently, {{ interface("nsIPrompt") }} defaults to using window-modal prompts. You can force a prompt to be tab-modal using code like this:</p>
<pre class="brush: js">
var theWindow = gBrowser.contentWindow;
let prompt = Components.classes["@mozilla.org/prompter;1"]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .getService(Components.interfaces.nsIPromptFactory)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .getPrompt(theWindow, Components.interfaces.nsIPrompt);

let bag = prompt.QueryInterface(Components.interfaces.nsIWritablePropertyBag2);
bag.setPropertyAsBool("allowTabModal", true);
</pre>
<p>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 {{ interface("nsIPrompt") }} object, <code>prompt</code>, as usual. For example:</p>
<pre class="brush: js">
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);</pre>
<p>{{ interface("nsIPrompt") }}&nbsp;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</p>
<p>To use other forms of the prompts of {{ interface("nsIPromptService") }} interface see the <a href="/en-US/docs/XPCOM_Interface_Reference/nsIPromptService#Example_code" title="/en-US/docs/XPCOM_Interface_Reference/nsIPromptService#Example_code">Example Code</a>. Then apply it, like in the example below, here we apply the prompt with a checkbox:</p>
<pre class="brush: js">
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]);</pre>
Revert to this revision