Bug 575485 - Refactor commonDialog code into a sharable JSM (Part 1, cleanup). r=gavin, a=beltzner

This commit is contained in:
Justin Dolske 2010-10-27 14:16:17 -07:00
Родитель fdc54df815
Коммит 2bc44d4e22
4 изменённых файлов: 63 добавлений и 87 удалений

Просмотреть файл

@ -46,17 +46,17 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
let gArgs = window.arguments[0].QueryInterface(Ci.nsIWritablePropertyBag2)
.QueryInterface(Ci.nsIWritablePropertyBag);
let promptType, numButtons, iconClass, soundID, hasInputField = true;
let gArgs, promptType, numButtons, iconClass, soundID, hasInputField = true;
let gDelayExpired = false, gBlurred = false;
function earlyInit() {
// This is called before onload fires, so we can't be certain that any elements
// in the document have their bindings ready, so don't call any methods/properties
// here on xul elements that come from xbl bindings.
gArgs = window.arguments[0].QueryInterface(Ci.nsIWritablePropertyBag2)
.QueryInterface(Ci.nsIWritablePropertyBag);
promptType = gArgs.getProperty("promptType");
switch (promptType) {
@ -124,7 +124,7 @@ function initTextbox(aName, aValue) {
document.getElementById(aName + "Textbox").setAttribute("value", aValue);
}
function setLabelForNode(aNode, aLabel, aIsLabelFlag) {
function setLabelForNode(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
@ -145,11 +145,7 @@ function setLabelForNode(aNode, aLabel, aIsLabelFlag) {
// && is the magic sequence to embed an & in your label.
aLabel = aLabel.replace(/\&\&/g, "&");
if (aIsLabelFlag) { // Set text for <label> element
aNode.setAttribute("value", aLabel);
} else { // Set text for other xul elements
aNode.label = aLabel;
}
aNode.label = aLabel;
// XXXjag bug 325251
// Need to set this after aNode.setAttribute("value", aLabel);
@ -174,44 +170,34 @@ function commonDialogOnLoad() {
// set the document title
let title = gArgs.getProperty("title");
#ifdef XP_MACOSX
document.getElementById("info.title").appendChild(document.createTextNode(title));
#else
document.title = title;
#endif
// OS X doesn't have a title on modal dialogs, this is hidden on other platforms.
document.getElementById("info.title").appendChild(document.createTextNode(title));
Services.obs.addObserver(softkbObserver, "softkb-change", false);
// Set button visibility
// Set button labels and visibility
let dialog = document.documentElement;
switch (numButtons) {
case 4:
setLabelForNode(dialog.getButton("extra2"), gArgs.getProperty("button3Label"));
dialog.getButton("extra2").hidden = false;
// fall through
case 3:
setLabelForNode(dialog.getButton("extra1"), gArgs.getProperty("button2Label"));
dialog.getButton("extra1").hidden = false;
// fall through
case 2:
if (gArgs.hasKey("button1Label"))
setLabelForNode(dialog.getButton("cancel"), gArgs.getProperty("button1Label"));
break;
case 1:
dialog.getButton("cancel").hidden = true;
break;
case 4:
dialog.getButton("extra2").hidden = false;
case 3:
dialog.getButton("extra1").hidden = false;
}
// Set button labels
switch (numButtons) {
case 4:
setLabelForNode(document.documentElement.getButton("extra2"), gArgs.getProperty("button3Label"));
// fall through
case 3:
setLabelForNode(document.documentElement.getButton("extra1"), gArgs.getProperty("button2Label"));
// fall through
default:
case 2:
if (gArgs.hasKey("button1Label"))
setLabelForNode(document.documentElement.getButton("cancel"), gArgs.getProperty("button1Label"));
// fall through
case 1:
if (gArgs.hasKey("button0Label"))
setLabelForNode(document.documentElement.getButton("accept"), gArgs.getProperty("button0Label"));
break;
}
if (gArgs.hasKey("button0Label"))
setLabelForNode(dialog.getButton("accept"), gArgs.getProperty("button0Label"));
// display the main text
// Bug 317334 - crop string length as a workaround.
@ -248,9 +234,9 @@ function commonDialogOnLoad() {
b = gArgs.getProperty("defaultButtonNum");
let dButton = dlgButtons[b];
// XXX shouldn't we set the default even when a textbox is focused?
document.documentElement.defaultButton = dButton;
dialog.defaultButton = dButton;
#ifndef XP_MACOSX
document.documentElement.getButton(dButton).focus();
dialog.getButton(dButton).focus();
#endif
} else {
if (promptType == "promptPassword")
@ -261,12 +247,13 @@ function commonDialogOnLoad() {
if (gArgs.hasKey("enableDelay") && gArgs.getProperty("enableDelay")) {
let delayInterval = Services.prefs.getIntPref("security.dialog_enable_delay");
document.documentElement.getButton("accept").disabled = true;
document.documentElement.getButton("extra1").disabled = true;
document.documentElement.getButton("extra2").disabled = true;
setTimeout(commonDialogReenableButtons, delayInterval);
setButtonsEnabledState(dialog, false);
setTimeout(function () {
// Don't automatically enable the buttons if we're not in the foreground
if (!gBlurred)
setButtonsEnabledState(dialog, true);
gDelayExpired = true;
}, delayInterval);
addEventListener("blur", commonDialogBlur, false);
addEventListener("focus", commonDialogFocus, false);
@ -286,46 +273,33 @@ function commonDialogOnLoad() {
Services.obs.notifyObservers(window, "common-dialog-loaded", null);
}
function setButtonsEnabledState(dialog, enabled) {
dialog.getButton("accept").disabled = !enabled;
dialog.getButton("extra1").disabled = !enabled;
dialog.getButton("extra2").disabled = !enabled;
}
function commonDialogOnUnload() {
Services.obs.removeObserver(softkbObserver, "softkb-change");
}
var gDelayExpired = false;
var gBlurred = false;
function commonDialogBlur(aEvent) {
if (aEvent.target != document)
return;
gBlurred = true;
document.documentElement.getButton("accept").disabled = true;
document.documentElement.getButton("extra1").disabled = true;
document.documentElement.getButton("extra2").disabled = true;
let dialog = document.documentElement;
setButtonsEnabledState(dialog, false);
}
function commonDialogFocus(aEvent) {
if (aEvent.target != document)
return;
gBlurred = false;
let dialog = document.documentElement;
// When refocusing the window, don't enable the buttons unless the countdown
// delay has expired.
if (gDelayExpired) {
let script;
script = "document.documentElement.getButton('accept').disabled = false; ";
script += "document.documentElement.getButton('extra1').disabled = false; ";
script += "document.documentElement.getButton('extra2').disabled = false;";
setTimeout(script, 250);
}
}
function commonDialogReenableButtons() {
// Don't automatically enable the buttons if we're not in the foreground
if (!gBlurred) {
document.documentElement.getButton("accept").disabled = false;
document.documentElement.getButton("extra1").disabled = false;
document.documentElement.getButton("extra2").disabled = false;
}
gDelayExpired = true;
if (gDelayExpired)
setTimeout(setButtonsEnabledState, 250, dialog, true);
}
function onCheckboxClick(aCheckboxElement) {

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://global/content/commonDialog.css" type="text/css"?>
@ -7,7 +7,7 @@
<!DOCTYPE dialog SYSTEM "chrome://global/locale/commonDialog.dtd">
<dialog id="commonDialog"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
aria-describedby="info.body"
onload="commonDialogOnLoad();"
onunload="commonDialogOnUnload();"
@ -15,7 +15,7 @@
ondialogextra1="return commonDialogOnExtra1();"
ondialogextra2="return commonDialogOnExtra2();"
buttonpack="center">
<script type="application/javascript" src="chrome://global/content/commonDialog.js"/>
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
@ -55,10 +55,12 @@
<image id="info.icon" class="spaced"/>
</hbox>
<vbox id="infoContainer">
#ifdef XP_MACOSX
<!-- Dialog title is inside dialog for OS X -->
<description id="info.title"/>
<!-- Only shown on OS X, since it has no dialog title -->
<description id="info.title"
#ifndef XP_MACOSX
style="display: none"
#endif
/>
<spacer style="height: 1em"/>
<description id="info.body" context="contentAreaContextMenu" noinitialfocus="true"/>
</vbox>
@ -80,8 +82,8 @@
<!-- This method is called inline because it may unset hidden="true" on the
above boxes, causing their frames to be build and bindings to load.
So, by calling this inline, we guarantee the textboxes and checkboxes
above boxes, causing their frames to be build and bindings to load.
So, by calling this inline, we guarantee the textboxes and checkboxes
above will have their bindings before initButtons is called, and the
dialog will be intrinsically sized correctly. -->
<script type="application/javascript">earlyInit();</script>

Просмотреть файл

@ -41,12 +41,12 @@ const Cr = Components.results;
const Cc = Components.classes;
const Cu = Components.utils;
let gArgs = window.arguments[0].QueryInterface(Ci.nsIWritablePropertyBag2)
.QueryInterface(Ci.nsIWritablePropertyBag);
let listBox;
let gArgs, listBox;
function dialogOnLoad() {
gArgs = window.arguments[0].QueryInterface(Ci.nsIWritablePropertyBag2)
.QueryInterface(Ci.nsIWritablePropertyBag);
let promptType = gArgs.getProperty("promptType");
if (promptType != "select") {
Cu.reportError("selectDialog opened for unknown type: " + promptType);

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -37,10 +37,10 @@
***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<!DOCTYPE dialog SYSTEM "chrome://global/locale/commonDialog.dtd">
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="dialogOnLoad()"
ondialogaccept="return dialogOK();">