зеркало из https://github.com/mozilla/gecko-dev.git
Have the LDAP autocomplete session return an error item on failure; the user can select this item and an alert box with more details will be popped up. r=ducarroz@netscape.com, sr=bienvenu@netscape.com
This commit is contained in:
Родитель
af3d887b1c
Коммит
249529744b
|
@ -51,6 +51,7 @@ REQUIRES = xpcom \
|
|||
mime \
|
||||
msgcompose \
|
||||
appcomps \
|
||||
intl \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
#include "nsILDAPMessage.h"
|
||||
#include "nsLDAP.h"
|
||||
#include "prlog.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIDNSService.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsAbLDAPAutoCompFormatter,
|
||||
nsILDAPAutoCompFormatter,
|
||||
|
@ -146,6 +149,215 @@ nsAbLDAPAutoCompFormatter::Format(nsILDAPMessage *aMsg,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbLDAPAutoCompFormatter::FormatException(PRInt32 aState,
|
||||
nsresult aErrorCode,
|
||||
nsIAutoCompleteItem **aItem)
|
||||
{
|
||||
PRInt32 errorKey;
|
||||
nsresult rv;
|
||||
|
||||
// create an nsIAutoCompleteItem to hold the returned value
|
||||
//
|
||||
nsCOMPtr<nsIAutoCompleteItem> item = do_CreateInstance(
|
||||
NS_AUTOCOMPLETEITEM_CONTRACTID, &rv);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsAbLDAPAutoCompFormatter::FormatException(): couldn't"
|
||||
" create " NS_AUTOCOMPLETEITEM_CONTRACTID "\n");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// get the string bundle service
|
||||
//
|
||||
nsXPIDLString errMsg, ldapErrMsg, errCode, alertMsg, ldapHint;
|
||||
nsString errCodeNum;
|
||||
|
||||
nsCOMPtr<nsIStringBundleService> stringBundleSvc(do_GetService(
|
||||
NS_STRINGBUNDLE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsAbLDAPAutoCompleteFormatter::FormatException():"
|
||||
" error getting string bundle service");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// get the string bundles relevant here: the main LDAP bundle,
|
||||
// and the ldap AutoCompletion-specific bundle
|
||||
//
|
||||
nsCOMPtr<nsIStringBundle> ldapBundle, ldapACBundle;
|
||||
|
||||
rv = stringBundleSvc->CreateBundle(
|
||||
"chrome://mozldap/locale/ldapErrors.properties",
|
||||
getter_AddRefs(ldapBundle));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsAbLDAPAutoCompleteFormatter::FormatException():"
|
||||
" error creating string bundle"
|
||||
" chrome://mozldap/locale/ldapErrors.properties");
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = stringBundleSvc->CreateBundle(
|
||||
"chrome://global/locale/ldapAutoCompErrs.properties",
|
||||
getter_AddRefs(ldapACBundle));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsAbLDAPAutoCompleteFormatter::FormatException():"
|
||||
" error creating string bundle"
|
||||
" chrome://global/locale/ldapAutoCompErrs.properties");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// get the general error that goes in the dropdown and the window
|
||||
// title
|
||||
//
|
||||
rv = ldapACBundle->GetStringFromID(aState, getter_Copies(errMsg));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsAbLDAPAutoCompleteFormatter::FormatException():"
|
||||
" error getting general error from bundle"
|
||||
" chrome://global/locale/ldapAutoCompErrs.properties");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// get the phrase corresponding to "Error code"
|
||||
//
|
||||
rv = ldapACBundle->GetStringFromName(NS_LITERAL_STRING("errCode").get(),
|
||||
getter_Copies(errCode));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsAbLDAPAutoCompleteFormatter::FormatException"
|
||||
"(): error getting 'errCode' string from bundle "
|
||||
"chrome://mozldap/locale/ldapErrors.properties");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// for LDAP errors
|
||||
//
|
||||
if (NS_ERROR_GET_MODULE(aErrorCode) == NS_ERROR_MODULE_LDAP) {
|
||||
|
||||
errorKey = NS_ERROR_GET_CODE(aErrorCode);
|
||||
|
||||
// put the number itself in string form
|
||||
//
|
||||
errCodeNum.AppendInt(errorKey);
|
||||
|
||||
// get the LDAP error message itself
|
||||
//
|
||||
rv = ldapBundle->GetStringFromID(NS_ERROR_GET_CODE(aErrorCode),
|
||||
getter_Copies(ldapErrMsg));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsAbLDAPAutoCompleteFormatter::FormatException"
|
||||
"(): error getting string 2 from bundle "
|
||||
"chrome://mozldap/locale/ldapErrors.properties");
|
||||
return rv;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// put the entire nsresult in string form
|
||||
//
|
||||
errCodeNum += NS_LITERAL_STRING("0x");
|
||||
errCodeNum.AppendInt(aErrorCode, 16);
|
||||
|
||||
// figure out the key to index into the string bundle
|
||||
//
|
||||
const PRInt32 HOST_NOT_FOUND_ERROR=5000;
|
||||
const PRInt32 GENERIC_ERROR=9999;
|
||||
errorKey = ( (aErrorCode == NS_ERROR_UNKNOWN_HOST) ?
|
||||
HOST_NOT_FOUND_ERROR : GENERIC_ERROR );
|
||||
|
||||
// get the specific error message itself
|
||||
rv = ldapACBundle->GetStringFromID(errorKey,
|
||||
getter_Copies(ldapErrMsg));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsAbLDAPAutoCompleteFormatter::FormatException"
|
||||
"(): error getting specific non LDAP error-string "
|
||||
"from bundle "
|
||||
"chrome://mozldap/locale/ldapErrors.properties");
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// and try to find a hint about what the user should do next
|
||||
//
|
||||
const PRInt32 HINT_BASE=10000;
|
||||
const PRInt32 GENERIC_HINT_CODE = 9999;
|
||||
rv = ldapACBundle->GetStringFromID(HINT_BASE + errorKey,
|
||||
getter_Copies(ldapHint));
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = ldapACBundle->GetStringFromID(HINT_BASE + GENERIC_HINT_CODE,
|
||||
getter_Copies(ldapHint));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsAbLDAPAutoCompleteFormatter::FormatException()"
|
||||
"(): error getting hint string from bundle "
|
||||
"chrome://mozldap/locale/ldapErrors.properties");
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
const PRUnichar *stringParams[4] = { errCode.get(), errCodeNum.get(),
|
||||
ldapErrMsg.get(), ldapHint.get() };
|
||||
|
||||
rv = ldapACBundle->FormatStringFromName(
|
||||
NS_LITERAL_STRING("alertFormat").get(), stringParams, 4,
|
||||
getter_Copies(alertMsg));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("YYY");
|
||||
}
|
||||
|
||||
// put the error message, between angle brackets, into the XPIDL |value|
|
||||
// attribute. Note that the hardcoded string is only used since
|
||||
// stringbundles have already failed us.
|
||||
//
|
||||
if (errMsg.Length()) {
|
||||
rv = item->SetValue(PromiseFlatString(NS_LITERAL_STRING("<") + errMsg
|
||||
+ NS_LITERAL_STRING(">")));
|
||||
} else {
|
||||
rv = item->SetValue(
|
||||
NS_LITERAL_STRING("<Unknown LDAP autocompletion error>"));
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("nsAbLDAPAutoCompFormatter::FormatException(): "
|
||||
"item->SetValue failed");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// pass the alert message in as the param; if that fails, proceed anyway
|
||||
//
|
||||
nsCOMPtr<nsISupportsWString> alert(do_CreateInstance(
|
||||
NS_SUPPORTS_WSTRING_CONTRACTID,
|
||||
&rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("nsAbLDAPAutoCompFormatter::FormatException(): "
|
||||
"could not create nsISupportsWString");
|
||||
} else {
|
||||
rv = alert->SetData(alertMsg.get());
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("nsAbLDAPAutoCompFormatter::FormatException(): "
|
||||
"alert.Set() failed");
|
||||
} else {
|
||||
rv = item->SetParam(alert);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("nsAbLDAPAutoCompFormatter::FormatException(): "
|
||||
"item->SetParam failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this is a remote addresbook, set the class name so the autocomplete
|
||||
// item can be styled to show this
|
||||
//
|
||||
rv = item->SetClassName("remote-err");
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("nsAbLDAPAutoCompleteFormatter::FormatException():"
|
||||
" item->SetClassName() failed");
|
||||
}
|
||||
|
||||
// all done; return the item
|
||||
//
|
||||
NS_IF_ADDREF(*aItem = item);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbLDAPAutoCompFormatter::GetAttributes(PRUint32 *aCount, char ** *aAttrs)
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@ top.MAX_RECIPIENTS = 0;
|
|||
var inputElementType = "";
|
||||
var selectElementType = "";
|
||||
var selectElementIndexTable = null;
|
||||
var gPromptService = null;
|
||||
|
||||
var test_addresses_sequence = false;
|
||||
if (prefs)
|
||||
|
@ -150,7 +151,7 @@ function CompFields2Recipients(msgCompFields, msgType)
|
|||
//If it's a new message, we need to add an extrat empty recipient.
|
||||
if (!msgTo && !msgNewsgroups)
|
||||
_awSetInputAndPopup("", "addr_to", newTreeChildrenNode, templateNode);
|
||||
dump("replacing child in comp fields 2 recips \n");
|
||||
// dump("replacing child in comp fields 2 recips \n");
|
||||
var parent = treeChildren.parentNode;
|
||||
parent.replaceChild(newTreeChildrenNode, treeChildren);
|
||||
awFitDummyRows();
|
||||
|
@ -350,7 +351,7 @@ function awClickEmptySpace(targ, setFocus)
|
|||
if (targ.localName != 'treechildren')
|
||||
return;
|
||||
|
||||
dump("awClickEmptySpace\n");
|
||||
// dump("awClickEmptySpace\n");
|
||||
var lastInput = awGetInputElement(top.MAX_RECIPIENTS);
|
||||
|
||||
if ( lastInput && lastInput.value )
|
||||
|
@ -751,6 +752,61 @@ function awRecipientTextCommand(userAction, element)
|
|||
awReturnHit(element);
|
||||
}
|
||||
|
||||
// Called when an autocomplete session item is selected and the status of
|
||||
// the session it was selected from is nsIAutoCompleteStatus::failureItems.
|
||||
//
|
||||
// As of this writing, the only way that can happen is when an LDAP
|
||||
// autocomplete session returns an error to be displayed to the user.
|
||||
//
|
||||
// There are hardcoded messages in here, but these are just fallbacks for
|
||||
// when string bundles have already failed us.
|
||||
//
|
||||
function awRecipientErrorCommand(errItem, element)
|
||||
{
|
||||
// remove the angle brackets from the general error message to construct
|
||||
// the title for the alert. someday we'll pass this info using a real
|
||||
// exception object, and then this code can go away.
|
||||
//
|
||||
var generalErrString;
|
||||
if (errItem.value != "") {
|
||||
generalErrString = errItem.value.slice(1, errItem.value.length-1);
|
||||
} else {
|
||||
generalErrString = "Unknown LDAP server problem encountered";
|
||||
}
|
||||
|
||||
// try and get the string of the specific error to contruct the complete
|
||||
// err msg, otherwise fall back to something generic. This message is
|
||||
// handed to us as an nsISupportsWString in the param slot of the
|
||||
// autocomplete error item, by agreement documented in
|
||||
// nsILDAPAutoCompFormatter.idl
|
||||
//
|
||||
var specificErrString = "";
|
||||
try {
|
||||
var specificError = errItem.param.QueryInterface(
|
||||
Components.interfaces.nsISupportsWString);
|
||||
specificErrString = specificError.data;
|
||||
} catch (ex) {
|
||||
}
|
||||
if (specificErrString == "") {
|
||||
specificErrString = "Internal error";
|
||||
}
|
||||
|
||||
try {
|
||||
if (!gPromptService) {
|
||||
gPromptService = Components.classes[
|
||||
"@mozilla.org/embedcomp/prompt-service;1"].getService().
|
||||
QueryInterface(Components.interfaces.nsIPromptService);
|
||||
}
|
||||
} catch (ex) {
|
||||
}
|
||||
|
||||
if (gPromptService) {
|
||||
gPromptService.alert(window, generalErrString, specificErrString);
|
||||
} else {
|
||||
window.alert(generalErrString + ": " + specificErrString);
|
||||
}
|
||||
}
|
||||
|
||||
function awRecipientKeyPress(event, element)
|
||||
{
|
||||
switch(event.keyCode) {
|
||||
|
|
|
@ -64,6 +64,7 @@ Rights Reserved.
|
|||
autoFill="true" autoFillAfterMatch="true" forceComplete="true"
|
||||
minResultsForPopup="3"
|
||||
ontextcommand="awRecipientTextCommand(userAction, this)"
|
||||
onerrorcommand="awRecipientErrorCommand(errItem, this)"
|
||||
oninput="setupAutocomplete();" disableonsend="true"
|
||||
onkeypress="awRecipientKeyPress(event, this)"
|
||||
onkeydown="awRecipientKeyDown(event, this)">
|
||||
|
|
Загрузка…
Ссылка в новой задаче