Back to index

lightning-sunbird  0.9+nobinonly
nsPrompt.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsIServiceManager.h"
00039 #include "nsIAuthPromptWrapper.h"
00040 #include "nsPrompt.h"
00041 #include "nsReadableUtils.h"
00042 #include "nsDependentString.h"
00043 #include "nsIDOMDocument.h"
00044 #include "nsIDOMDocumentEvent.h"
00045 #include "nsIDOMEventTarget.h"
00046 #include "nsIDOMEvent.h"
00047 #include "nsIPrivateDOMEvent.h"
00048 #include "nsEmbedCID.h"
00049 #include "nsPIDOMWindow.h"
00050 
00051 nsresult
00052 NS_NewPrompter(nsIPrompt **result, nsIDOMWindow *aParent)
00053 {
00054   nsresult rv;
00055   *result = 0;
00056 
00057   nsPrompt *prompter = new nsPrompt(aParent);
00058   if (!prompter)
00059     return NS_ERROR_OUT_OF_MEMORY;
00060 
00061   NS_ADDREF(prompter);
00062   rv = prompter->Init();
00063   if (NS_FAILED(rv)) {
00064     NS_RELEASE(prompter);
00065     return rv;
00066   }
00067 
00068   *result = prompter;
00069   return NS_OK;
00070 }
00071 
00072 nsresult
00073 NS_NewAuthPrompter(nsIAuthPrompt **result, nsIDOMWindow *aParent)
00074 {
00075 
00076   nsresult rv;
00077   *result = 0;
00078 
00079   nsPrompt *prompter = new nsPrompt(aParent);
00080   if (!prompter)
00081     return NS_ERROR_OUT_OF_MEMORY;
00082 
00083   NS_ADDREF(prompter);
00084   rv = prompter->Init();
00085   if (NS_FAILED(rv)) {
00086     NS_RELEASE(prompter);
00087     return rv;
00088   }
00089 
00090   *result = prompter;
00091   // wrap the base prompt in an nsIAuthPromptWrapper, if available
00092   // the impl used here persists prompt data and pre-fills the dialogs
00093   nsCOMPtr<nsIAuthPromptWrapper> siPrompt =
00094     do_CreateInstance("@mozilla.org/wallet/single-sign-on-prompt;1");
00095   if (siPrompt) {
00096     // then single sign-on is installed
00097     rv = siPrompt->SetPromptDialogs(prompter);
00098     if (NS_SUCCEEDED(rv)) {
00099       *result = siPrompt;
00100       NS_RELEASE(prompter); // siPrompt is a strong owner
00101       NS_ADDREF(*result);
00102     }
00103   }
00104   return NS_OK;
00105 }
00106 
00107 NS_IMPL_THREADSAFE_ISUPPORTS2(nsPrompt, nsIPrompt, nsIAuthPrompt)
00108 
00109 nsPrompt::nsPrompt(nsIDOMWindow *aParent)
00110   : mParent(aParent)
00111 {
00112 #ifdef DEBUG
00113   {
00114     nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(aParent));
00115 
00116     NS_ASSERTION(!win || win->IsOuterWindow(),
00117                  "Inner window passed as nsPrompt parent!");
00118   }
00119 #endif
00120 }
00121 
00122 nsresult
00123 nsPrompt::Init()
00124 {
00125   mPromptService = do_GetService(NS_PROMPTSERVICE_CONTRACTID);
00126   return mPromptService ? NS_OK : NS_ERROR_FAILURE;
00127 }
00128 
00129 //*****************************************************************************
00130 // nsPrompt::nsIPrompt
00131 //*****************************************************************************
00132 
00133 class nsAutoWindowStateHelper
00134 {
00135 public:
00136   nsAutoWindowStateHelper(nsIDOMWindow *aWindow);
00137   ~nsAutoWindowStateHelper();
00138 
00139   PRBool DefaultEnabled()
00140   {
00141     return mDefaultEnabled;
00142   }
00143 
00144 protected:
00145   PRBool DispatchCustomEvent(const char *aEventName);
00146 
00147   nsIDOMWindow *mWindow;
00148   PRBool mDefaultEnabled;
00149 };
00150 
00151 nsAutoWindowStateHelper::nsAutoWindowStateHelper(nsIDOMWindow *aWindow)
00152   : mWindow(aWindow),
00153     mDefaultEnabled(DispatchCustomEvent("DOMWillOpenModalDialog"))
00154 {
00155   nsCOMPtr<nsPIDOMWindow_MOZILLA_1_8_BRANCH> window =
00156     do_QueryInterface(aWindow);
00157 
00158   if (window) {
00159     window->EnterModalState();
00160   }
00161 }
00162 
00163 nsAutoWindowStateHelper::~nsAutoWindowStateHelper()
00164 {
00165   nsCOMPtr<nsPIDOMWindow_MOZILLA_1_8_BRANCH> window =
00166     do_QueryInterface(mWindow);
00167 
00168   if (window) {
00169     window->LeaveModalState();
00170   }
00171 
00172   if (mDefaultEnabled) {
00173     DispatchCustomEvent("DOMModalDialogClosed");
00174   }
00175 }
00176 
00177 PRBool
00178 nsAutoWindowStateHelper::DispatchCustomEvent(const char *aEventName)
00179 {
00180   if (!mWindow) {
00181     return PR_TRUE;
00182   }
00183 
00184 #ifdef DEBUG
00185   {
00186     nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mWindow));
00187 
00188     NS_ASSERTION(window->GetExtantDocument() != nsnull,
00189                  "nsPrompt used too early on window object!");
00190   }
00191 #endif
00192 
00193   nsCOMPtr<nsIDOMDocument> domdoc;
00194   mWindow->GetDocument(getter_AddRefs(domdoc));
00195 
00196   nsCOMPtr<nsIDOMDocumentEvent> docevent(do_QueryInterface(domdoc));
00197   nsCOMPtr<nsIDOMEvent> event;
00198 
00199   PRBool defaultActionEnabled = PR_TRUE;
00200 
00201   if (docevent) {
00202     docevent->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
00203 
00204     nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
00205     if (privateEvent) {
00206       event->InitEvent(NS_ConvertASCIItoUTF16(aEventName), PR_TRUE, PR_TRUE);
00207 
00208       privateEvent->SetTrusted(PR_TRUE);
00209 
00210       nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(mWindow));
00211 
00212       target->DispatchEvent(event, &defaultActionEnabled);
00213     }
00214   }
00215 
00216   return defaultActionEnabled;
00217 }
00218 
00219 
00220 NS_IMETHODIMP
00221 nsPrompt::Alert(const PRUnichar* dialogTitle, 
00222                 const PRUnichar* text)
00223 {
00224   nsAutoWindowStateHelper windowStateHelper(mParent);
00225 
00226   if (!windowStateHelper.DefaultEnabled()) {
00227     return NS_OK;
00228   }
00229 
00230   return mPromptService->Alert(mParent, dialogTitle, text);
00231 }
00232 
00233 NS_IMETHODIMP
00234 nsPrompt::AlertCheck(const PRUnichar* dialogTitle, 
00235                      const PRUnichar* text,
00236                      const PRUnichar* checkMsg,
00237                      PRBool *checkValue)
00238 {
00239   nsAutoWindowStateHelper windowStateHelper(mParent);
00240 
00241   if (!windowStateHelper.DefaultEnabled()) {
00242     return NS_OK;
00243   }
00244 
00245   return mPromptService->AlertCheck(mParent, dialogTitle, text, checkMsg,
00246                                     checkValue);
00247 }
00248 
00249 NS_IMETHODIMP
00250 nsPrompt::Confirm(const PRUnichar* dialogTitle, 
00251                   const PRUnichar* text,
00252                   PRBool *_retval)
00253 {
00254   nsAutoWindowStateHelper windowStateHelper(mParent);
00255 
00256   if (!windowStateHelper.DefaultEnabled()) {
00257     return NS_OK;
00258   }
00259 
00260   return mPromptService->Confirm(mParent, dialogTitle, text, _retval);
00261 }
00262 
00263 NS_IMETHODIMP
00264 nsPrompt::ConfirmCheck(const PRUnichar* dialogTitle, 
00265                        const PRUnichar* text,
00266                        const PRUnichar* checkMsg,
00267                        PRBool *checkValue,
00268                        PRBool *_retval)
00269 {
00270   nsAutoWindowStateHelper windowStateHelper(mParent);
00271 
00272   if (!windowStateHelper.DefaultEnabled()) {
00273     return NS_OK;
00274   }
00275 
00276   return mPromptService->ConfirmCheck(mParent, dialogTitle, text, checkMsg,
00277                                       checkValue, _retval);
00278 }
00279 
00280 NS_IMETHODIMP
00281 nsPrompt::ConfirmEx(const PRUnichar *dialogTitle,
00282                     const PRUnichar *text,
00283                     PRUint32 buttonFlags,
00284                     const PRUnichar *button0Title,
00285                     const PRUnichar *button1Title,
00286                     const PRUnichar *button2Title,
00287                     const PRUnichar *checkMsg,
00288                     PRBool *checkValue,
00289                     PRInt32 *buttonPressed)
00290 {
00291   nsAutoWindowStateHelper windowStateHelper(mParent);
00292 
00293   if (!windowStateHelper.DefaultEnabled()) {
00294     return NS_OK;
00295   }
00296 
00297   return mPromptService->ConfirmEx(mParent, dialogTitle, text, buttonFlags,
00298                                    button0Title, button1Title, button2Title,
00299                                    checkMsg, checkValue, buttonPressed);
00300 }
00301 
00302 NS_IMETHODIMP
00303 nsPrompt::Prompt(const PRUnichar *dialogTitle,
00304                  const PRUnichar *text,
00305                  PRUnichar **answer,
00306                  const PRUnichar *checkMsg,
00307                  PRBool *checkValue,
00308                  PRBool *_retval)
00309 {
00310   nsAutoWindowStateHelper windowStateHelper(mParent);
00311 
00312   if (!windowStateHelper.DefaultEnabled()) {
00313     return NS_OK;
00314   }
00315 
00316   return mPromptService->Prompt(mParent, dialogTitle, text, answer, checkMsg,
00317                                 checkValue, _retval);
00318 }
00319 
00320 NS_IMETHODIMP
00321 nsPrompt::PromptUsernameAndPassword(const PRUnichar *dialogTitle,
00322                                     const PRUnichar *text,
00323                                     PRUnichar **username,
00324                                     PRUnichar **password,
00325                                     const PRUnichar *checkMsg,
00326                                     PRBool *checkValue,
00327                                     PRBool *_retval)
00328 {
00329   nsAutoWindowStateHelper windowStateHelper(mParent);
00330 
00331   if (!windowStateHelper.DefaultEnabled()) {
00332     return NS_OK;
00333   }
00334 
00335   return mPromptService->PromptUsernameAndPassword(mParent, dialogTitle, text,
00336                                                    username, password,
00337                                                    checkMsg, checkValue,
00338                                                    _retval);
00339 }
00340 
00341 NS_IMETHODIMP
00342 nsPrompt::PromptPassword(const PRUnichar *dialogTitle,
00343                          const PRUnichar *text,
00344                          PRUnichar **password,
00345                          const PRUnichar *checkMsg,
00346                          PRBool *checkValue,
00347                          PRBool *_retval)
00348 {
00349   nsAutoWindowStateHelper windowStateHelper(mParent);
00350 
00351   if (!windowStateHelper.DefaultEnabled()) {
00352     return NS_OK;
00353   }
00354 
00355   return mPromptService->PromptPassword(mParent, dialogTitle, text, password,
00356                                         checkMsg, checkValue, _retval);
00357 }
00358 
00359 NS_IMETHODIMP
00360 nsPrompt::Select(const PRUnichar *dialogTitle,
00361                  const PRUnichar* inMsg,
00362                  PRUint32 inCount, 
00363                  const PRUnichar **inList,
00364                  PRInt32 *outSelection,
00365                  PRBool *_retval)
00366 {
00367   nsAutoWindowStateHelper windowStateHelper(mParent);
00368 
00369   if (!windowStateHelper.DefaultEnabled()) {
00370     return NS_OK;
00371   }
00372 
00373   return mPromptService->Select(mParent, dialogTitle, inMsg, inCount, inList,
00374                                 outSelection, _retval);
00375 }
00376 
00377 //*****************************************************************************
00378 // nsPrompt::nsIAuthPrompt
00379 // This implementation serves as glue between nsIAuthPrompt and nsIPrompt
00380 // when a single-signon was not available.
00381 //*****************************************************************************   
00382 
00383 NS_IMETHODIMP
00384 nsPrompt::Prompt(const PRUnichar* dialogTitle,
00385                  const PRUnichar* text,
00386                  const PRUnichar* passwordRealm,
00387                  PRUint32 savePassword,
00388                  const PRUnichar* defaultText,
00389                  PRUnichar* *result,
00390                  PRBool *_retval)
00391 {
00392   nsAutoWindowStateHelper windowStateHelper(mParent);
00393 
00394   if (!windowStateHelper.DefaultEnabled()) {
00395     return NS_OK;
00396   }
00397 
00398   // Ignore passwordRealm and savePassword
00399   if (defaultText) {
00400     *result = ToNewUnicode(nsDependentString(defaultText));
00401 
00402     if (!*result) {
00403       return NS_ERROR_OUT_OF_MEMORY;
00404     }
00405   }
00406 
00407   return mPromptService->Prompt(mParent, dialogTitle, text, result, nsnull,
00408                                 nsnull, _retval);
00409 }
00410 
00411 NS_IMETHODIMP
00412 nsPrompt::PromptUsernameAndPassword(const PRUnichar* dialogTitle, 
00413                                     const PRUnichar* text,
00414                                     const PRUnichar* passwordRealm,
00415                                     PRUint32 savePassword,
00416                                     PRUnichar* *user,
00417                                     PRUnichar* *pwd,
00418                                     PRBool *_retval)
00419 {
00420   nsAutoWindowStateHelper windowStateHelper(mParent);
00421 
00422   if (!windowStateHelper.DefaultEnabled()) {
00423     return NS_OK;
00424   }
00425 
00426   // Ignore passwordRealm and savePassword
00427   return mPromptService->PromptUsernameAndPassword(mParent, dialogTitle, text,
00428                                                    user, pwd, nsnull, nsnull,
00429                                                    _retval);
00430 }
00431 
00432 NS_IMETHODIMP
00433 nsPrompt::PromptPassword(const PRUnichar* dialogTitle, 
00434                          const PRUnichar* text,
00435                          const PRUnichar* passwordRealm,
00436                          PRUint32 savePassword,
00437                          PRUnichar* *pwd,
00438                          PRBool *_retval)
00439 {
00440   nsAutoWindowStateHelper windowStateHelper(mParent);
00441 
00442   if (!windowStateHelper.DefaultEnabled()) {
00443     return NS_OK;
00444   }
00445 
00446   // Ignore passwordRealm and savePassword
00447   return mPromptService->PromptPassword(mParent, dialogTitle, text, pwd,
00448                                         nsnull, nsnull, _retval);
00449 }