--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -7433,16 +7433,23 @@ let DownloadMonitorPanel = {
function getNotificationBox(aWindow) {
var foundBrowser = gBrowser.getBrowserForDocument(aWindow.document);
if (foundBrowser)
return gBrowser.getNotificationBox(foundBrowser)
return null;
};
+function getTabModalPromptBox(aWindow) {
+ var foundBrowser = gBrowser.getBrowserForDocument(aWindow.document);
+ if (foundBrowser)
+ return gBrowser.getTabModalPromptBox(foundBrowser)
+ return null;
+};
+
/* DEPRECATED */
function getBrowser() gBrowser;
function getNavToolbox() gNavToolbox;
let gPrivateBrowsingUI = {
_privateBrowsingService: null,
_searchBarValue: null,
_findBarValue: null,
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -285,16 +285,68 @@
<parameter name="aBrowser"/>
<body>
<![CDATA[
return (aBrowser || this.mCurrentBrowser).parentNode.parentNode;
]]>
</body>
</method>
+ <method name="getTabModalPromptBox">
+ <parameter name="aBrowser"/>
+ <body>
+ <![CDATA[
+ const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ let browser = (aBrowser || this.mCurrentBrowser);
+ let stack = browser.parentNode;
+ let self = this;
+
+ 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);
+ newPrompt.clientTop; // style flush to assure binding is attached
+
+ let tab = self._getTabForContentWindow(browser.contentWindow);
+ newPrompt.init(args, tab, onCloseCallback);
+ return newPrompt;
+ },
+
+ removePrompt : function(aPrompt) {
+ let count = parseInt(browser.getAttribute("tabmodalPromptShowing"));
+ count--;
+ if (count)
+ browser.setAttribute("tabmodalPromptShowing", count);
+ else
+ browser.removeAttribute("tabmodalPromptShowing");
+ stack.removeChild(aPrompt);
+ },
+
+ 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]);
+ return prompts;
+ },
+ };
+
+ return promptBox;
+ ]]>
+ </body>
+ </method>
+
<method name="_callProgressListeners">
<parameter name="aBrowser"/>
<parameter name="aMethod"/>
<parameter name="aArguments"/>
<parameter name="aCallGlobalListeners"/>
<parameter name="aCallTabsListeners"/>
<body><![CDATA[
var rv = true;
--- a/toolkit/components/prompts/content/commonDialog.js
+++ b/toolkit/components/prompts/content/commonDialog.js
@@ -58,16 +58,17 @@ function commonDialogOnLoad() {
while (propEnum.hasMoreElements()) {
let prop = propEnum.getNext().QueryInterface(Ci.nsIProperty);
args[prop.name] = prop.value;
}
let dialog = document.documentElement;
let ui = {
+ prompt : window,
loginContainer : document.getElementById("loginContainer"),
loginTextbox : document.getElementById("loginTextbox"),
loginLabel : document.getElementById("loginLabel"),
password1Container : document.getElementById("password1Container"),
password1Textbox : document.getElementById("password1Textbox"),
password1Label : document.getElementById("password1Label"),
infoBody : document.getElementById("info.body"),
infoTitle : document.getElementById("info.title"),
new file mode 100644
--- /dev/null
+++ b/toolkit/components/prompts/content/tabprompts.xml
@@ -0,0 +1,238 @@
+<?xml version="1.0"?>
+<!DOCTYPE bindings [
+<!ENTITY % commonDialogDTD SYSTEM "chrome://global/locale/commonDialog.dtd">
+<!ENTITY % dialogOverlayDTD SYSTEM "chrome://global/locale/dialogOverlay.dtd">
+%commonDialogDTD;
+%dialogOverlayDTD;
+]>
+
+<bindings id="tabPrompts"
+ xmlns="http://www.mozilla.org/xbl"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:xbl="http://www.mozilla.org/xbl">
+
+ <binding id="tabmodalprompt">
+
+ <resources>
+ <stylesheet src="chrome://global/skin/tabprompts.css"/>
+ </resources>
+
+ <xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <!-- This is based on the guts of commonDialog.xul -->
+ <spacer flex="1"/>
+ <hbox>
+ <spacer flex="1"/>
+ <vbox class="mainContainer">
+ <grid class="topContainer">
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+
+ <rows>
+ <row>
+ <hbox align="start">
+ <image anonid="info.icon" class="info.icon"/>
+ </hbox>
+ <vbox class="infoContainer">
+ <description anonid="info.title" hidden="true"/>
+ <description anonid="info.body" class="info.body"/>
+ </vbox>
+ </row>
+
+ <row anonid="loginContainer" hidden="true" align="center">
+ <label anonid="loginLabel" value="&editfield0.label;" control="loginTextbox"/>
+ <textbox anonid="loginTextbox"/>
+ </row>
+
+ <row anonid="password1Container" hidden="true" align="center">
+ <label anonid="password1Label" value="&editfield1.label;" control="password1Textbox"/>
+ <textbox anonid="password1Textbox" type="password"/>
+ </row>
+
+ <row anonid="checkboxContainer" hidden="true">
+ <spacer/>
+ <checkbox anonid="checkbox"/>
+ </row>
+ </rows>
+ </grid>
+ <xbl:children/>
+ <hbox class="buttonContainer">
+#ifdef XP_UNIX
+ <button anonid="button3" hidden="true"/>
+ <button anonid="button2" hidden="true"/>
+ <spacer anonid="buttonSpacer" flex="1"/>
+ <button anonid="button1" label="&cancelButton.label;"/>
+ <button anonid="button0" label="&okButton.label;"/>
+#else
+ <button anonid="button3" hidden="true"/>
+ <spacer anonid="buttonSpacer" flex="1" hidden="true"/>
+ <button anonid="button0" label="&okButton.label;"/>
+ <button anonid="button2" hidden="true"/>
+ <button anonid="button1" label="&cancelButton.label;"/>
+#endif
+ </hbox>
+ </vbox>
+ <spacer flex="1"/>
+ </hbox>
+ <spacer flex="2"/>
+ </xbl:content>
+
+ <implementation implements="nsIDOMEventListener">
+ <constructor>
+ <![CDATA[
+ let self = this;
+ function getElement(anonid) {
+ return document.getAnonymousElementByAttribute(self, "anonid", anonid);
+ }
+
+ this.ui = {
+ prompt : this,
+ loginContainer : getElement("loginContainer"),
+ loginTextbox : getElement("loginTextbox"),
+ loginLabel : getElement("loginLabel"),
+ password1Container : getElement("password1Container"),
+ password1Textbox : getElement("password1Textbox"),
+ password1Label : getElement("password1Label"),
+ infoBody : getElement("info.body"),
+ infoTitle : getElement("info.title"),
+ infoIcon : getElement("info.icon"),
+ checkbox : getElement("checkbox"),
+ checkboxContainer : getElement("checkboxContainer"),
+ button3 : getElement("button3"),
+ button2 : getElement("button2"),
+ button1 : getElement("button1"),
+ button0 : getElement("button0"),
+ // focusTarget (for BUTTON_DELAY_ENABLE) not yet supported
+ };
+
+ this.ui.button0.addEventListener("command", this.onButtonClick.bind(this, 0), false);
+ this.ui.button1.addEventListener("command", this.onButtonClick.bind(this, 1), false);
+ this.ui.button2.addEventListener("command", this.onButtonClick.bind(this, 2), false);
+ this.ui.button3.addEventListener("command", this.onButtonClick.bind(this, 3), false);
+ // Anonymous wrapper used here because |Dialog| doesn't exist until init() is called!
+ this.ui.checkbox.addEventListener("command", function() { self.Dialog.onCheckbox(); } , false);
+ ]]>
+ </constructor>
+
+ <field name="ui"/>
+ <field name="args"/>
+ <field name="linkedTab"/>
+ <field name="onCloseCallback"/>
+ <field name="Dialog"/>
+
+ <method name="init">
+ <parameter name="args"/>
+ <parameter name="linkedTab"/>
+ <parameter name="onCloseCallback"/>
+ <body>
+ <![CDATA[
+ this.args = args;
+ this.linkedTab = linkedTab;
+ this.onCloseCallback = onCloseCallback;
+
+ if (args.enableDelay)
+ throw "BUTTON_DELAY_ENABLE not yet supported for tab-modal prompts";
+
+ // We need to remove the prompt when the tab or browser window is closed or
+ // the page navigates, else we never unwind the event loop and that's sad times.
+ // Remember to cleanup in shutdownPrompt()!
+ linkedTab.addEventListener("TabClose", this, false);
+ window.addEventListener("unload", this, false);
+ this.args.domWindow.addEventListener("pagehide", this, false);
+
+ let tmp = {};
+ Components.utils.import("resource://gre/modules/CommonDialog.jsm", tmp);
+ this.Dialog = new tmp.CommonDialog(args, this.ui);
+ this.Dialog.onLoad(null);
+
+ // TODO: should unhide buttonSpacer on Windows when there are 4 buttons.
+ // Better yet, just drop support for 4-button dialogs. (bug 609510)
+ ]]>
+ </body>
+ </method>
+
+ <method name="shutdownPrompt">
+ <body>
+ <![CDATA[
+ // remove our event listeners
+ try {
+ this.linkedTab.removeEventListener("TabClose", this, false);
+ window.removeEventListener("unload", this, false);
+ this.args.domWindow.removeEventListener("pagehide", this, false);
+ } catch(e) { }
+ // invoke callback
+ this.onCloseCallback();
+ ]]>
+ </body>
+ </method>
+
+ <method name="handleEvent">
+ <parameter name="aEvent"/>
+ <body>
+ <![CDATA[
+ switch (aEvent.type) {
+ case "TabClose":
+ case "unload":
+ case "pagehide":
+ this.Dialog.abortPrompt();
+ this.shutdownPrompt();
+ break;
+ }
+ ]]>
+ </body>
+ </method>
+
+ <method name="onButtonClick">
+ <parameter name="buttonNum"/>
+ <body>
+ <![CDATA[
+ this.Dialog["onButton" + buttonNum]();
+ this.shutdownPrompt();
+ ]]>
+ </body>
+ </method>
+
+ <method name="onKeyAction">
+ <parameter name="action"/>
+ <parameter name="event"/>
+ <body>
+ <![CDATA[
+ if (event.getPreventDefault())
+ return;
+
+ if (action == "default") {
+ let bnum = this.args.defaultButtonNum || 0;
+ let button = this.ui["button" + bnum];
+ if (!button.hasAttribute("default"))
+ return;
+ this.onButtonClick(button);
+ } else { // action == "cancel"
+ this.onButtonClick(1); // Cancel button
+ }
+ ]]>
+ </body>
+ </method>
+ </implementation>
+
+ <handlers>
+ <!-- Based on dialog.xml handlers -->
+ <handler event="keypress" keycode="VK_ENTER"
+ group="system" action="this.onKeyAction('default', event);"/>
+ <handler event="keypress" keycode="VK_RETURN"
+ group="system" action="this.onKeyAction('default', event);"/>
+ <handler event="keypress" keycode="VK_ESCAPE"
+ group="system" action="this.onKeyAction('cancel', event);"/>
+#ifndef XP_MACOSX
+ <handler event="focus" phase="capturing">
+ // Focus shift clears the default button.
+ let bnum = this.args.defaultButtonNum || 0;
+ let button = this.ui["button" + bnum];
+ button.setAttribute("default", event.originalTarget == button);
+ </handler>
+#endif
+ </handlers>
+
+ </binding>
+</bindings>
--- a/toolkit/components/prompts/jar.mn
+++ b/toolkit/components/prompts/jar.mn
@@ -1,6 +1,7 @@
toolkit.jar:
*+ content/global/commonDialog.js (content/commonDialog.js)
*+ content/global/commonDialog.xul (content/commonDialog.xul)
content/global/commonDialog.css (content/commonDialog.css)
+ content/global/selectDialog.js (content/selectDialog.js)
+ content/global/selectDialog.xul (content/selectDialog.xul)
+*+ content/global/tabprompts.xml (content/tabprompts.xml)
--- a/toolkit/components/prompts/src/CommonDialog.jsm
+++ b/toolkit/components/prompts/src/CommonDialog.jsm
@@ -188,20 +188,21 @@ CommonDialog.prototype = {
if (this.args.defaultButtonNum)
b = this.args.defaultButtonNum;
let button = this.ui["button" + b];
if (xulDialog) {
xulDialog.defaultButton = ['accept', 'cancel', 'extra1', 'extra2'][b];
let isOSX = ("nsILocalFileMac" in Components.interfaces);
if (!isOSX)
button.focus();
+ } else {
+ button.setAttribute("default", "true");
+ button.focus();
}
- // TODO:
- // else
- // (tabmodal prompts need to set a default button for Enter to act upon)
+
} else {
if (this.args.promptType == "promptPassword")
this.ui.password1Textbox.select();
else
this.ui.loginTextbox.select();
}
if (this.args.enableDelay) {
@@ -218,21 +219,20 @@ CommonDialog.prototype = {
try {
if (this.soundID) {
Cc["@mozilla.org/sound;1"].
createInstance(Ci.nsISound).
playEventSound(soundID);
}
} catch (e) { }
- if (xulDialog)
- Services.obs.notifyObservers(xulDialog.ownerDocument.defaultView, "common-dialog-loaded", null);
- // TODO:
- // else
- // (notify using what as the subject?)
+ let topic = "common-dialog-loaded";
+ if (!xulDialog)
+ topic = "tabmodal-dialog-loaded";
+ Services.obs.notifyObservers(this.ui.prompt, topic, null);
},
setLabelForNode: function(aNode, aLabel) {
// This is for labels which may contain embedded access keys.
// If we end in (&X) where X represents the access key, optionally preceded
// by spaces and/or followed by the ':' character, store the access key and
// remove the access key placeholder + leading spaces from the label.
// Otherwise a character preceded by one but not two &s is the access key.
@@ -310,16 +310,17 @@ CommonDialog.prototype = {
this.setButtonsEnabledState(true);
},
onCheckbox : function() {
this.args.checked = this.ui.checkbox.checked;
},
onButton0 : function() {
+ this.args.promptActive = false;
this.args.ok = true;
this.args.buttonNumClicked = 0;
let username = this.ui.loginTextbox.value;
let password = this.ui.password1Textbox.value;
// Return textfield values
switch (this.args.promptType) {
@@ -332,19 +333,28 @@ CommonDialog.prototype = {
break;
case "promptPassword":
this.args.pass = password;
break;
}
},
onButton1 : function() {
+ this.args.promptActive = false;
this.args.buttonNumClicked = 1;
},
onButton2 : function() {
+ this.args.promptActive = false;
this.args.buttonNumClicked = 2;
},
onButton3 : function() {
+ this.args.promptActive = false;
this.args.buttonNumClicked = 3;
},
+
+ abortPrompt : function() {
+ this.args.promptActive = false;
+ this.args.promptAborted = true;
+ },
+
};
--- a/toolkit/components/prompts/src/nsPrompter.js
+++ b/toolkit/components/prompts/src/nsPrompter.js
@@ -336,16 +336,45 @@ let PromptUtils = {
propBagToObject : function (propBag, obj) {
// Here we iterate over the object's original properties, not the bag
// (ie, the prompt can't return more/different properties than were
// passed in). This just helps ensure that the caller provides default
// values, lest the prompt forget to set them.
for (let propName in obj)
obj[propName] = propBag.getProperty(propName);
},
+
+ getTabModalPrompt : function (domWin) {
+ var promptBox = null;
+
+ // Given a content DOM window, returns the chrome window it's in.
+ function getChromeWindow(aWindow) {
+ var chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell)
+ .chromeEventHandler.ownerDocument.defaultView;
+ return chromeWin;
+ }
+
+ try {
+ // Get the topmost window, in case we're in a frame.
+ var promptWin = domWin.top;
+
+ // Get the chrome window for the content window we're using.
+ // (Unwrap because we need a non-IDL property below.)
+ var chromeWin = getChromeWindow(promptWin).wrappedJSObject;
+
+ if (chromeWin.getTabModalPromptBox)
+ promptBox = chromeWin.getTabModalPromptBox(promptWin);
+ } catch (e) {
+ // If any errors happen, just assume no tabmodal prompter.
+ }
+
+ return promptBox;
+ },
};
XPCOMUtils.defineLazyGetter(PromptUtils, "strBundle", function () {
let bunService = Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService);
let bundle = bunService.createBundle("chrome://global/locale/commonDialogs.properties");
if (!bundle)
throw "String bundle for Prompter not present!";
@@ -358,42 +387,101 @@ XPCOMUtils.defineLazyGetter(PromptUtils,
ellipsis = Services.prefs.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data;
} catch (e) { }
return ellipsis;
});
function openModalWindow(domWin, uri, args) {
- // XXX do we want to do modal state if we fall back to .activeWindow?
+ // XXX Investigate supressing modal state when we're called without a
+ // window? Seems odd to affect whatever window happens to be active.
if (!domWin)
domWin = Services.ww.activeWindow;
- // XXX domWin may still be null here if there are _no_ windows open.
+ // domWin may still be null here if there are _no_ windows open.
// Note that we don't need to fire DOMWillOpenModalDialog and
// DOMModalDialogClosed events here, wwatcher's OpenWindowJSInternal
// will do that. Similarly for enterModalState / leaveModalState.
Services.ww.openWindow(domWin, uri, "_blank", "centerscreen,chrome,modal,titlebar", args);
}
+function openTabPrompt(domWin, tabPrompt, args) {
+ let winUtils = domWin.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ winUtils.enterModalState();
+
+ // We provide a callback so the prompt can close itself. We don't want to
+ // wait for this event loop to return... Otherwise the presence of other
+ // prompts on the call stack would in this dialog appearing unresponsive
+ // until the other prompts had been closed.
+ let callbackInvoked = false;
+ function onPromptClose(forceCleanup) {
+ if (!newPrompt && !forceCleanup)
+ return;
+ callbackInvoked = true;
+ if (newPrompt)
+ tabPrompt.removePrompt(newPrompt);
+ winUtils.leaveModalState();
+ }
+
+ let newPrompt;
+ try {
+ // tab-modal prompts need to watch for navigation changes, give it the
+ // domWindow to watch for pagehide events.
+ args.domWindow = domWin;
+ args.promptActive = true;
+
+ newPrompt = tabPrompt.appendPrompt(args, onPromptClose);
+
+ // TODO since we don't actually open a window, need to check if
+ // there's other stuff in nsWindowWatcher::OpenWindowJSInternal
+ // that we might need to do here as well.
+
+ let thread = Services.tm.currentThread;
+ while (args.promptActive)
+ thread.processNextEvent(true);
+ delete args.promptActive;
+
+ if (args.promptAborted)
+ throw Components.Exception("prompt aborted by user", Cr.NS_ERROR_NOT_AVAILABLE);
+ } finally {
+ // If the prompt unexpectedly failed to invoke the callback, do so here.
+ if (!callbackInvoked)
+ onPromptClose(true);
+ }
+}
+
function ModalPrompter(domWin) {
this.domWin = domWin;
}
ModalPrompter.prototype = {
domWin : null,
+ allowTabModal : true,
QueryInterface : XPCOMUtils.generateQI([Ci.nsIPrompt, Ci.nsIAuthPrompt, Ci.nsIAuthPrompt2]),
/* ---------- internal methods ---------- */
openPrompt : function (args) {
+ let allowTabModal = this.allowTabModal;
+
+ if (allowTabModal && this.domWin) {
+ let tabPrompt = PromptUtils.getTabModalPrompt(this.domWin);
+ if (tabPrompt) {
+ openTabPrompt(this.domWin, tabPrompt, args);
+ return;
+ }
+ }
+
+ // If we can't do a tab modal prompt, fallback to using a window-modal dialog.
const COMMON_DIALOG = "chrome://global/content/commonDialog.xul";
const SELECT_DIALOG = "chrome://global/content/selectDialog.xul";
let uri = (args.promptType == "select") ? SELECT_DIALOG : COMMON_DIALOG;
let propBag = PromptUtils.objectToPropBag(args);
openModalWindow(this.domWin, uri, propBag);
PromptUtils.propBagToObject(propBag, args);
--- a/toolkit/components/prompts/test/prompt_common.js
+++ b/toolkit/components/prompts/test/prompt_common.js
@@ -66,21 +66,21 @@ function getTabModalPromptBox(domWin) {
var chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.chromeEventHandler.ownerDocument.defaultView;
return chromeWin;
}
try {
- // Get topmost window, in case we're in a frame.
- var promptWin = domWin.top
+ // Get the topmost window, in case we're in a frame.
+ var promptWin = domWin.top;
// Get the chrome window for the content window we're using.
- // .wrappedJSObject needed here -- see bug 422974 comment 5.
+ // (Unwrap because we need a non-IDL property below.)
var chromeWin = getChromeWindow(promptWin).wrappedJSObject;
if (chromeWin.getTabModalPromptBox)
promptBox = chromeWin.getTabModalPromptBox(promptWin);
} catch (e) {
// If any errors happen, just assume no tabmodal prompter.
}
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -1174,8 +1174,13 @@ findbar {
-moz-binding: url("chrome://global/content/bindings/findbar.xml#findbar-textbox");
}
/*********** filefield ************/
filefield {
-moz-binding: url("chrome://global/content/bindings/filefield.xml#filefield");
}
+
+/*********** tabmodalprompt ************/
+tabmodalprompt {
+ -moz-binding: url("chrome://global/content/tabprompts.xml#tabmodalprompt");
+}
--- a/toolkit/themes/pinstripe/global/jar.mn
+++ b/toolkit/themes/pinstripe/global/jar.mn
@@ -37,16 +37,17 @@ toolkit.jar:
skin/classic/global/radio.css
skin/classic/global/resizer.css
skin/classic/global/richlistbox.css
skin/classic/global/scrollbars.css (nativescrollbars.css)
* skin/classic/global/scale.css
skin/classic/global/scrollbox.css
skin/classic/global/spinbuttons.css
skin/classic/global/splitter.css
+ skin/classic/global/tabprompts.css
skin/classic/global/tabbox.css
skin/classic/global/textbox.css
skin/classic/global/datetimepicker.css
skin/classic/global/toolbar.css
skin/classic/global/toolbarbutton.css
skin/classic/global/tree.css
* skin/classic/global/viewbuttons.css
* skin/classic/global/webConsole.css
new file mode 100644
--- /dev/null
+++ b/toolkit/themes/pinstripe/global/tabprompts.css
@@ -0,0 +1,27 @@
+/* Tab Modal Prompt boxes */
+tabmodalprompt {
+ width: 100%;
+ height: 100%;
+ color: white;
+ background-image: -moz-repeating-linear-gradient(-45deg,
+ rgba(65, 65, 65, 0.8),
+ rgba(65, 65, 65, 0.8) 20px,
+ rgba(69, 69, 69, 0.8) 20px,
+ rgba(69, 69, 69, 0.8) 40px);
+ -moz-box-pack: center;
+ -moz-box-orient: vertical;
+}
+
+.mainContainer {
+ min-width: 20em;
+ padding: 10px;
+ background: rgb(80,80,80);
+ border: 1px solid rgb(20,20,20);
+ border-radius: 12px;
+ box-shadow: inset 0 1px 3.5px rgba(0,0,0,0.8),
+ 0 1px 0 rgba(255,255,255,0.2);
+}
+
+.topContainer {
+ min-height: 64px;
+}
--- a/toolkit/themes/winstripe/global/jar.mn
+++ b/toolkit/themes/winstripe/global/jar.mn
@@ -44,16 +44,17 @@ toolkit.jar:
skin/classic/global/resizer.css
skin/classic/global/richlistbox.css
* skin/classic/global/scale.css
skin/classic/global/scrollbars.css (xulscrollbars.css)
skin/classic/global/scrollbox.css
skin/classic/global/spinbuttons.css
skin/classic/global/splitter.css
skin/classic/global/tabbox.css
+ skin/classic/global/tabprompts.css
skin/classic/global/textbox.css
* skin/classic/global/toolbar.css
skin/classic/global/toolbarbutton.css
skin/classic/global/tree.css
* skin/classic/global/webConsole.css
* skin/classic/global/webConsole_networkPanel.css
skin/classic/global/wizard.css
skin/classic/global/alerts/alert.css (alerts/alert.css)
@@ -216,16 +217,17 @@ toolkit.jar:
skin/classic/aero/global/resizer.css
skin/classic/aero/global/richlistbox.css
* skin/classic/aero/global/scale.css
skin/classic/aero/global/scrollbars.css (xulscrollbars.css)
skin/classic/aero/global/scrollbox.css
skin/classic/aero/global/spinbuttons.css
skin/classic/aero/global/splitter.css
skin/classic/aero/global/tabbox.css
+ skin/classic/aero/global/tabprompts.css
* skin/classic/aero/global/textbox.css (textbox-aero.css)
* skin/classic/aero/global/toolbar.css
* skin/classic/aero/global/toolbarbutton.css (toolbarbutton-aero.css)
* skin/classic/aero/global/tree.css (tree-aero.css)
* skin/classic/aero/global/webConsole.css
* skin/classic/aero/global/webConsole_networkPanel.css
skin/classic/aero/global/wizard.css
skin/classic/aero/global/alerts/alert.css (alerts/alert.css)
new file mode 100644
--- /dev/null
+++ b/toolkit/themes/winstripe/global/tabprompts.css
@@ -0,0 +1,31 @@
+/* Tab Modal Prompt boxes */
+tabmodalprompt {
+ width: 100%;
+ height: 100%;
+ color: white;
+ background-image: -moz-repeating-linear-gradient(-45deg,
+ rgba(65, 65, 65, 0.8),
+ rgba(65, 65, 65, 0.8) 20px,
+ rgba(69, 69, 69, 0.8) 20px,
+ rgba(69, 69, 69, 0.8) 40px);
+ -moz-box-pack: center;
+ -moz-box-orient: vertical;
+}
+
+.mainContainer {
+ min-width: 20em;
+ padding: 10px;
+ background: rgb(80,80,80);
+ border: 1px solid rgb(20,20,20);
+ border-radius: 12px;
+ box-shadow: inset 0 1px 3.5px rgba(0,0,0,0.8),
+ 0 1px 0 rgba(255,255,255,0.2);
+}
+
+.topContainer {
+ min-height: 64px;
+}
+
+.buttonContainer {
+ -moz-box-pack: center;
+}