1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/alerts/nsXULAlerts.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,159 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsXULAlerts.h" 1.10 + 1.11 +#include "nsAutoPtr.h" 1.12 +#include "mozilla/LookAndFeel.h" 1.13 +#include "nsIServiceManager.h" 1.14 +#include "nsISupportsArray.h" 1.15 +#include "nsISupportsPrimitives.h" 1.16 +#include "nsPIDOMWindow.h" 1.17 +#include "nsIWindowWatcher.h" 1.18 + 1.19 +using namespace mozilla; 1.20 + 1.21 +#define ALERT_CHROME_URL "chrome://global/content/alerts/alert.xul" 1.22 + 1.23 +NS_IMPL_ISUPPORTS(nsXULAlertObserver, nsIObserver) 1.24 + 1.25 +NS_IMETHODIMP 1.26 +nsXULAlertObserver::Observe(nsISupports* aSubject, const char* aTopic, 1.27 + const char16_t* aData) 1.28 +{ 1.29 + if (!strcmp("alertfinished", aTopic)) { 1.30 + nsIDOMWindow* currentAlert = mXULAlerts->mNamedWindows.GetWeak(mAlertName); 1.31 + // The window in mNamedWindows might be a replacement, thus it should only 1.32 + // be removed if it is the same window that is associated with this listener. 1.33 + if (currentAlert == mAlertWindow) { 1.34 + mXULAlerts->mNamedWindows.Remove(mAlertName); 1.35 + } 1.36 + } 1.37 + 1.38 + nsresult rv = NS_OK; 1.39 + if (mObserver) { 1.40 + rv = mObserver->Observe(aSubject, aTopic, aData); 1.41 + } 1.42 + return rv; 1.43 +} 1.44 + 1.45 +nsresult 1.46 +nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle, 1.47 + const nsAString& aAlertText, bool aAlertTextClickable, 1.48 + const nsAString& aAlertCookie, nsIObserver* aAlertListener, 1.49 + const nsAString& aAlertName, const nsAString& aBidi, 1.50 + const nsAString& aLang) 1.51 +{ 1.52 + nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); 1.53 + 1.54 + nsCOMPtr<nsISupportsArray> argsArray; 1.55 + nsresult rv = NS_NewISupportsArray(getter_AddRefs(argsArray)); 1.56 + NS_ENSURE_SUCCESS(rv, rv); 1.57 + 1.58 + // create scriptable versions of our strings that we can store in our nsISupportsArray.... 1.59 + nsCOMPtr<nsISupportsString> scriptableImageUrl (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); 1.60 + NS_ENSURE_TRUE(scriptableImageUrl, NS_ERROR_FAILURE); 1.61 + 1.62 + scriptableImageUrl->SetData(aImageUrl); 1.63 + rv = argsArray->AppendElement(scriptableImageUrl); 1.64 + NS_ENSURE_SUCCESS(rv, rv); 1.65 + 1.66 + nsCOMPtr<nsISupportsString> scriptableAlertTitle (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); 1.67 + NS_ENSURE_TRUE(scriptableAlertTitle, NS_ERROR_FAILURE); 1.68 + 1.69 + scriptableAlertTitle->SetData(aAlertTitle); 1.70 + rv = argsArray->AppendElement(scriptableAlertTitle); 1.71 + NS_ENSURE_SUCCESS(rv, rv); 1.72 + 1.73 + nsCOMPtr<nsISupportsString> scriptableAlertText (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); 1.74 + NS_ENSURE_TRUE(scriptableAlertText, NS_ERROR_FAILURE); 1.75 + 1.76 + scriptableAlertText->SetData(aAlertText); 1.77 + rv = argsArray->AppendElement(scriptableAlertText); 1.78 + NS_ENSURE_SUCCESS(rv, rv); 1.79 + 1.80 + nsCOMPtr<nsISupportsPRBool> scriptableIsClickable (do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID)); 1.81 + NS_ENSURE_TRUE(scriptableIsClickable, NS_ERROR_FAILURE); 1.82 + 1.83 + scriptableIsClickable->SetData(aAlertTextClickable); 1.84 + rv = argsArray->AppendElement(scriptableIsClickable); 1.85 + NS_ENSURE_SUCCESS(rv, rv); 1.86 + 1.87 + nsCOMPtr<nsISupportsString> scriptableAlertCookie (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); 1.88 + NS_ENSURE_TRUE(scriptableAlertCookie, NS_ERROR_FAILURE); 1.89 + 1.90 + scriptableAlertCookie->SetData(aAlertCookie); 1.91 + rv = argsArray->AppendElement(scriptableAlertCookie); 1.92 + NS_ENSURE_SUCCESS(rv, rv); 1.93 + 1.94 + nsCOMPtr<nsISupportsPRInt32> scriptableOrigin (do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID)); 1.95 + NS_ENSURE_TRUE(scriptableOrigin, NS_ERROR_FAILURE); 1.96 + 1.97 + int32_t origin = 1.98 + LookAndFeel::GetInt(LookAndFeel::eIntID_AlertNotificationOrigin); 1.99 + scriptableOrigin->SetData(origin); 1.100 + 1.101 + rv = argsArray->AppendElement(scriptableOrigin); 1.102 + NS_ENSURE_SUCCESS(rv, rv); 1.103 + 1.104 + nsCOMPtr<nsISupportsString> scriptableBidi (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); 1.105 + NS_ENSURE_TRUE(scriptableBidi, NS_ERROR_FAILURE); 1.106 + 1.107 + scriptableBidi->SetData(aBidi); 1.108 + rv = argsArray->AppendElement(scriptableBidi); 1.109 + NS_ENSURE_SUCCESS(rv, rv); 1.110 + 1.111 + nsCOMPtr<nsISupportsString> scriptableLang (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); 1.112 + NS_ENSURE_TRUE(scriptableLang, NS_ERROR_FAILURE); 1.113 + 1.114 + scriptableLang->SetData(aLang); 1.115 + rv = argsArray->AppendElement(scriptableLang); 1.116 + NS_ENSURE_SUCCESS(rv, rv); 1.117 + 1.118 + // Alerts with the same name should replace the old alert in the same position. 1.119 + // Provide the new alert window with a pointer to the replaced window so that 1.120 + // it may take the same position. 1.121 + nsCOMPtr<nsISupportsInterfacePointer> replacedWindow = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv); 1.122 + NS_ENSURE_TRUE(replacedWindow, NS_ERROR_FAILURE); 1.123 + nsIDOMWindow* previousAlert = mNamedWindows.GetWeak(aAlertName); 1.124 + replacedWindow->SetData(previousAlert); 1.125 + replacedWindow->SetDataIID(&NS_GET_IID(nsIDOMWindow)); 1.126 + rv = argsArray->AppendElement(replacedWindow); 1.127 + NS_ENSURE_SUCCESS(rv, rv); 1.128 + 1.129 + // Add an observer (that wraps aAlertListener) to remove the window from 1.130 + // mNamedWindows when it is closed. 1.131 + nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv); 1.132 + NS_ENSURE_SUCCESS(rv, rv); 1.133 + nsRefPtr<nsXULAlertObserver> alertObserver = new nsXULAlertObserver(this, aAlertName, aAlertListener); 1.134 + nsCOMPtr<nsISupports> iSupports(do_QueryInterface(alertObserver)); 1.135 + ifptr->SetData(iSupports); 1.136 + ifptr->SetDataIID(&NS_GET_IID(nsIObserver)); 1.137 + rv = argsArray->AppendElement(ifptr); 1.138 + NS_ENSURE_SUCCESS(rv, rv); 1.139 + 1.140 + nsCOMPtr<nsIDOMWindow> newWindow; 1.141 + rv = wwatch->OpenWindow(0, ALERT_CHROME_URL, "_blank", 1.142 + "chrome,dialog=yes,titlebar=no,popup=yes", argsArray, 1.143 + getter_AddRefs(newWindow)); 1.144 + NS_ENSURE_SUCCESS(rv, rv); 1.145 + 1.146 + mNamedWindows.Put(aAlertName, newWindow); 1.147 + alertObserver->SetAlertWindow(newWindow); 1.148 + 1.149 + return NS_OK; 1.150 +} 1.151 + 1.152 +nsresult 1.153 +nsXULAlerts::CloseAlert(const nsAString& aAlertName) 1.154 +{ 1.155 + nsIDOMWindow* alert = mNamedWindows.GetWeak(aAlertName); 1.156 + nsCOMPtr<nsPIDOMWindow> domWindow = do_QueryInterface(alert); 1.157 + if (domWindow) { 1.158 + domWindow->DispatchCustomEvent("XULAlertClose"); 1.159 + } 1.160 + return NS_OK; 1.161 +} 1.162 +