|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "nsXULAlerts.h" |
|
7 |
|
8 #include "nsAutoPtr.h" |
|
9 #include "mozilla/LookAndFeel.h" |
|
10 #include "nsIServiceManager.h" |
|
11 #include "nsISupportsArray.h" |
|
12 #include "nsISupportsPrimitives.h" |
|
13 #include "nsPIDOMWindow.h" |
|
14 #include "nsIWindowWatcher.h" |
|
15 |
|
16 using namespace mozilla; |
|
17 |
|
18 #define ALERT_CHROME_URL "chrome://global/content/alerts/alert.xul" |
|
19 |
|
20 NS_IMPL_ISUPPORTS(nsXULAlertObserver, nsIObserver) |
|
21 |
|
22 NS_IMETHODIMP |
|
23 nsXULAlertObserver::Observe(nsISupports* aSubject, const char* aTopic, |
|
24 const char16_t* aData) |
|
25 { |
|
26 if (!strcmp("alertfinished", aTopic)) { |
|
27 nsIDOMWindow* currentAlert = mXULAlerts->mNamedWindows.GetWeak(mAlertName); |
|
28 // The window in mNamedWindows might be a replacement, thus it should only |
|
29 // be removed if it is the same window that is associated with this listener. |
|
30 if (currentAlert == mAlertWindow) { |
|
31 mXULAlerts->mNamedWindows.Remove(mAlertName); |
|
32 } |
|
33 } |
|
34 |
|
35 nsresult rv = NS_OK; |
|
36 if (mObserver) { |
|
37 rv = mObserver->Observe(aSubject, aTopic, aData); |
|
38 } |
|
39 return rv; |
|
40 } |
|
41 |
|
42 nsresult |
|
43 nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle, |
|
44 const nsAString& aAlertText, bool aAlertTextClickable, |
|
45 const nsAString& aAlertCookie, nsIObserver* aAlertListener, |
|
46 const nsAString& aAlertName, const nsAString& aBidi, |
|
47 const nsAString& aLang) |
|
48 { |
|
49 nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); |
|
50 |
|
51 nsCOMPtr<nsISupportsArray> argsArray; |
|
52 nsresult rv = NS_NewISupportsArray(getter_AddRefs(argsArray)); |
|
53 NS_ENSURE_SUCCESS(rv, rv); |
|
54 |
|
55 // create scriptable versions of our strings that we can store in our nsISupportsArray.... |
|
56 nsCOMPtr<nsISupportsString> scriptableImageUrl (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); |
|
57 NS_ENSURE_TRUE(scriptableImageUrl, NS_ERROR_FAILURE); |
|
58 |
|
59 scriptableImageUrl->SetData(aImageUrl); |
|
60 rv = argsArray->AppendElement(scriptableImageUrl); |
|
61 NS_ENSURE_SUCCESS(rv, rv); |
|
62 |
|
63 nsCOMPtr<nsISupportsString> scriptableAlertTitle (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); |
|
64 NS_ENSURE_TRUE(scriptableAlertTitle, NS_ERROR_FAILURE); |
|
65 |
|
66 scriptableAlertTitle->SetData(aAlertTitle); |
|
67 rv = argsArray->AppendElement(scriptableAlertTitle); |
|
68 NS_ENSURE_SUCCESS(rv, rv); |
|
69 |
|
70 nsCOMPtr<nsISupportsString> scriptableAlertText (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); |
|
71 NS_ENSURE_TRUE(scriptableAlertText, NS_ERROR_FAILURE); |
|
72 |
|
73 scriptableAlertText->SetData(aAlertText); |
|
74 rv = argsArray->AppendElement(scriptableAlertText); |
|
75 NS_ENSURE_SUCCESS(rv, rv); |
|
76 |
|
77 nsCOMPtr<nsISupportsPRBool> scriptableIsClickable (do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID)); |
|
78 NS_ENSURE_TRUE(scriptableIsClickable, NS_ERROR_FAILURE); |
|
79 |
|
80 scriptableIsClickable->SetData(aAlertTextClickable); |
|
81 rv = argsArray->AppendElement(scriptableIsClickable); |
|
82 NS_ENSURE_SUCCESS(rv, rv); |
|
83 |
|
84 nsCOMPtr<nsISupportsString> scriptableAlertCookie (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); |
|
85 NS_ENSURE_TRUE(scriptableAlertCookie, NS_ERROR_FAILURE); |
|
86 |
|
87 scriptableAlertCookie->SetData(aAlertCookie); |
|
88 rv = argsArray->AppendElement(scriptableAlertCookie); |
|
89 NS_ENSURE_SUCCESS(rv, rv); |
|
90 |
|
91 nsCOMPtr<nsISupportsPRInt32> scriptableOrigin (do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID)); |
|
92 NS_ENSURE_TRUE(scriptableOrigin, NS_ERROR_FAILURE); |
|
93 |
|
94 int32_t origin = |
|
95 LookAndFeel::GetInt(LookAndFeel::eIntID_AlertNotificationOrigin); |
|
96 scriptableOrigin->SetData(origin); |
|
97 |
|
98 rv = argsArray->AppendElement(scriptableOrigin); |
|
99 NS_ENSURE_SUCCESS(rv, rv); |
|
100 |
|
101 nsCOMPtr<nsISupportsString> scriptableBidi (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); |
|
102 NS_ENSURE_TRUE(scriptableBidi, NS_ERROR_FAILURE); |
|
103 |
|
104 scriptableBidi->SetData(aBidi); |
|
105 rv = argsArray->AppendElement(scriptableBidi); |
|
106 NS_ENSURE_SUCCESS(rv, rv); |
|
107 |
|
108 nsCOMPtr<nsISupportsString> scriptableLang (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); |
|
109 NS_ENSURE_TRUE(scriptableLang, NS_ERROR_FAILURE); |
|
110 |
|
111 scriptableLang->SetData(aLang); |
|
112 rv = argsArray->AppendElement(scriptableLang); |
|
113 NS_ENSURE_SUCCESS(rv, rv); |
|
114 |
|
115 // Alerts with the same name should replace the old alert in the same position. |
|
116 // Provide the new alert window with a pointer to the replaced window so that |
|
117 // it may take the same position. |
|
118 nsCOMPtr<nsISupportsInterfacePointer> replacedWindow = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv); |
|
119 NS_ENSURE_TRUE(replacedWindow, NS_ERROR_FAILURE); |
|
120 nsIDOMWindow* previousAlert = mNamedWindows.GetWeak(aAlertName); |
|
121 replacedWindow->SetData(previousAlert); |
|
122 replacedWindow->SetDataIID(&NS_GET_IID(nsIDOMWindow)); |
|
123 rv = argsArray->AppendElement(replacedWindow); |
|
124 NS_ENSURE_SUCCESS(rv, rv); |
|
125 |
|
126 // Add an observer (that wraps aAlertListener) to remove the window from |
|
127 // mNamedWindows when it is closed. |
|
128 nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv); |
|
129 NS_ENSURE_SUCCESS(rv, rv); |
|
130 nsRefPtr<nsXULAlertObserver> alertObserver = new nsXULAlertObserver(this, aAlertName, aAlertListener); |
|
131 nsCOMPtr<nsISupports> iSupports(do_QueryInterface(alertObserver)); |
|
132 ifptr->SetData(iSupports); |
|
133 ifptr->SetDataIID(&NS_GET_IID(nsIObserver)); |
|
134 rv = argsArray->AppendElement(ifptr); |
|
135 NS_ENSURE_SUCCESS(rv, rv); |
|
136 |
|
137 nsCOMPtr<nsIDOMWindow> newWindow; |
|
138 rv = wwatch->OpenWindow(0, ALERT_CHROME_URL, "_blank", |
|
139 "chrome,dialog=yes,titlebar=no,popup=yes", argsArray, |
|
140 getter_AddRefs(newWindow)); |
|
141 NS_ENSURE_SUCCESS(rv, rv); |
|
142 |
|
143 mNamedWindows.Put(aAlertName, newWindow); |
|
144 alertObserver->SetAlertWindow(newWindow); |
|
145 |
|
146 return NS_OK; |
|
147 } |
|
148 |
|
149 nsresult |
|
150 nsXULAlerts::CloseAlert(const nsAString& aAlertName) |
|
151 { |
|
152 nsIDOMWindow* alert = mNamedWindows.GetWeak(aAlertName); |
|
153 nsCOMPtr<nsPIDOMWindow> domWindow = do_QueryInterface(alert); |
|
154 if (domWindow) { |
|
155 domWindow->DispatchCustomEvent("XULAlertClose"); |
|
156 } |
|
157 return NS_OK; |
|
158 } |
|
159 |