|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set ts=2 sw=2 et tw=79: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "nsMimeTypeArray.h" |
|
8 |
|
9 #include "mozilla/dom/MimeTypeArrayBinding.h" |
|
10 #include "mozilla/dom/MimeTypeBinding.h" |
|
11 #include "nsIDOMNavigator.h" |
|
12 #include "nsPluginArray.h" |
|
13 #include "nsIMIMEService.h" |
|
14 #include "nsIMIMEInfo.h" |
|
15 #include "Navigator.h" |
|
16 #include "nsServiceManagerUtils.h" |
|
17 |
|
18 using namespace mozilla; |
|
19 using namespace mozilla::dom; |
|
20 |
|
21 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsMimeTypeArray) |
|
22 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsMimeTypeArray) |
|
23 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsMimeTypeArray) |
|
24 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY |
|
25 NS_INTERFACE_MAP_ENTRY(nsISupports) |
|
26 NS_INTERFACE_MAP_END |
|
27 |
|
28 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(nsMimeTypeArray, |
|
29 mWindow, |
|
30 mMimeTypes, |
|
31 mHiddenMimeTypes) |
|
32 |
|
33 nsMimeTypeArray::nsMimeTypeArray(nsPIDOMWindow* aWindow) |
|
34 : mWindow(aWindow) |
|
35 { |
|
36 SetIsDOMBinding(); |
|
37 } |
|
38 |
|
39 nsMimeTypeArray::~nsMimeTypeArray() |
|
40 { |
|
41 } |
|
42 |
|
43 JSObject* |
|
44 nsMimeTypeArray::WrapObject(JSContext* aCx) |
|
45 { |
|
46 return MimeTypeArrayBinding::Wrap(aCx, this); |
|
47 } |
|
48 |
|
49 void |
|
50 nsMimeTypeArray::Refresh() |
|
51 { |
|
52 mMimeTypes.Clear(); |
|
53 mHiddenMimeTypes.Clear(); |
|
54 } |
|
55 |
|
56 nsPIDOMWindow* |
|
57 nsMimeTypeArray::GetParentObject() const |
|
58 { |
|
59 MOZ_ASSERT(mWindow); |
|
60 return mWindow; |
|
61 } |
|
62 |
|
63 nsMimeType* |
|
64 nsMimeTypeArray::Item(uint32_t aIndex) |
|
65 { |
|
66 bool unused; |
|
67 return IndexedGetter(aIndex, unused); |
|
68 } |
|
69 |
|
70 nsMimeType* |
|
71 nsMimeTypeArray::NamedItem(const nsAString& aName) |
|
72 { |
|
73 bool unused; |
|
74 return NamedGetter(aName, unused); |
|
75 } |
|
76 |
|
77 nsMimeType* |
|
78 nsMimeTypeArray::IndexedGetter(uint32_t aIndex, bool &aFound) |
|
79 { |
|
80 aFound = false; |
|
81 |
|
82 EnsurePluginMimeTypes(); |
|
83 |
|
84 if (aIndex >= mMimeTypes.Length()) { |
|
85 return nullptr; |
|
86 } |
|
87 |
|
88 aFound = true; |
|
89 |
|
90 return mMimeTypes[aIndex]; |
|
91 } |
|
92 |
|
93 static nsMimeType* |
|
94 FindMimeType(const nsTArray<nsRefPtr<nsMimeType> >& aMimeTypes, |
|
95 const nsAString& aType) |
|
96 { |
|
97 for (uint32_t i = 0; i < aMimeTypes.Length(); ++i) { |
|
98 nsMimeType* mimeType = aMimeTypes[i]; |
|
99 if (aType.Equals(mimeType->Type())) { |
|
100 return mimeType; |
|
101 } |
|
102 } |
|
103 |
|
104 return nullptr; |
|
105 } |
|
106 |
|
107 nsMimeType* |
|
108 nsMimeTypeArray::NamedGetter(const nsAString& aName, bool &aFound) |
|
109 { |
|
110 aFound = false; |
|
111 |
|
112 EnsurePluginMimeTypes(); |
|
113 |
|
114 nsString lowerName(aName); |
|
115 ToLowerCase(lowerName); |
|
116 |
|
117 nsMimeType* mimeType = FindMimeType(mMimeTypes, lowerName); |
|
118 if (!mimeType) { |
|
119 mimeType = FindMimeType(mHiddenMimeTypes, lowerName); |
|
120 } |
|
121 |
|
122 if (mimeType) { |
|
123 aFound = true; |
|
124 return mimeType; |
|
125 } |
|
126 |
|
127 // Now let's check with the MIME service. |
|
128 nsCOMPtr<nsIMIMEService> mimeSrv = do_GetService("@mozilla.org/mime;1"); |
|
129 if (!mimeSrv) { |
|
130 return nullptr; |
|
131 } |
|
132 |
|
133 nsCOMPtr<nsIMIMEInfo> mimeInfo; |
|
134 mimeSrv->GetFromTypeAndExtension(NS_ConvertUTF16toUTF8(lowerName), |
|
135 EmptyCString(), getter_AddRefs(mimeInfo)); |
|
136 if (!mimeInfo) { |
|
137 return nullptr; |
|
138 } |
|
139 |
|
140 // Now we check whether we can really claim to support this type |
|
141 nsHandlerInfoAction action = nsIHandlerInfo::saveToDisk; |
|
142 mimeInfo->GetPreferredAction(&action); |
|
143 if (action != nsIMIMEInfo::handleInternally) { |
|
144 bool hasHelper = false; |
|
145 mimeInfo->GetHasDefaultHandler(&hasHelper); |
|
146 |
|
147 if (!hasHelper) { |
|
148 nsCOMPtr<nsIHandlerApp> helper; |
|
149 mimeInfo->GetPreferredApplicationHandler(getter_AddRefs(helper)); |
|
150 |
|
151 if (!helper) { |
|
152 // mime info from the OS may not have a PreferredApplicationHandler |
|
153 // so just check for an empty default description |
|
154 nsAutoString defaultDescription; |
|
155 mimeInfo->GetDefaultDescription(defaultDescription); |
|
156 |
|
157 if (defaultDescription.IsEmpty()) { |
|
158 // no support; just leave |
|
159 return nullptr; |
|
160 } |
|
161 } |
|
162 } |
|
163 } |
|
164 |
|
165 // If we got here, we support this type! Say so. |
|
166 aFound = true; |
|
167 |
|
168 // We don't want navigator.mimeTypes enumeration to expose MIME types with |
|
169 // application handlers, so add them to the list of hidden MIME types. |
|
170 nsMimeType *mt = new nsMimeType(mWindow, lowerName); |
|
171 mHiddenMimeTypes.AppendElement(mt); |
|
172 |
|
173 return mt; |
|
174 } |
|
175 |
|
176 bool |
|
177 nsMimeTypeArray::NameIsEnumerable(const nsAString& aName) |
|
178 { |
|
179 return true; |
|
180 } |
|
181 |
|
182 uint32_t |
|
183 nsMimeTypeArray::Length() |
|
184 { |
|
185 EnsurePluginMimeTypes(); |
|
186 |
|
187 return mMimeTypes.Length(); |
|
188 } |
|
189 |
|
190 void |
|
191 nsMimeTypeArray::GetSupportedNames(unsigned, nsTArray< nsString >& aRetval) |
|
192 { |
|
193 EnsurePluginMimeTypes(); |
|
194 |
|
195 for (uint32_t i = 0; i < mMimeTypes.Length(); ++i) { |
|
196 aRetval.AppendElement(mMimeTypes[i]->Type()); |
|
197 } |
|
198 } |
|
199 |
|
200 void |
|
201 nsMimeTypeArray::EnsurePluginMimeTypes() |
|
202 { |
|
203 if (!mMimeTypes.IsEmpty() || !mHiddenMimeTypes.IsEmpty() || !mWindow) { |
|
204 return; |
|
205 } |
|
206 |
|
207 nsCOMPtr<nsIDOMNavigator> navigator; |
|
208 mWindow->GetNavigator(getter_AddRefs(navigator)); |
|
209 |
|
210 if (!navigator) { |
|
211 return; |
|
212 } |
|
213 |
|
214 ErrorResult rv; |
|
215 nsPluginArray *pluginArray = |
|
216 static_cast<Navigator*>(navigator.get())->GetPlugins(rv); |
|
217 if (!pluginArray) { |
|
218 return; |
|
219 } |
|
220 |
|
221 pluginArray->GetMimeTypes(mMimeTypes, mHiddenMimeTypes); |
|
222 } |
|
223 |
|
224 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsMimeType, AddRef) |
|
225 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsMimeType, Release) |
|
226 |
|
227 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(nsMimeType, mWindow, mPluginElement) |
|
228 |
|
229 nsMimeType::nsMimeType(nsPIDOMWindow* aWindow, nsPluginElement* aPluginElement, |
|
230 uint32_t aPluginTagMimeIndex, const nsAString& aType) |
|
231 : mWindow(aWindow), |
|
232 mPluginElement(aPluginElement), |
|
233 mPluginTagMimeIndex(aPluginTagMimeIndex), |
|
234 mType(aType) |
|
235 { |
|
236 SetIsDOMBinding(); |
|
237 } |
|
238 |
|
239 nsMimeType::nsMimeType(nsPIDOMWindow* aWindow, const nsAString& aType) |
|
240 : mWindow(aWindow), |
|
241 mPluginElement(nullptr), |
|
242 mPluginTagMimeIndex(0), |
|
243 mType(aType) |
|
244 { |
|
245 SetIsDOMBinding(); |
|
246 } |
|
247 |
|
248 nsMimeType::~nsMimeType() |
|
249 { |
|
250 } |
|
251 |
|
252 nsPIDOMWindow* |
|
253 nsMimeType::GetParentObject() const |
|
254 { |
|
255 MOZ_ASSERT(mWindow); |
|
256 return mWindow; |
|
257 } |
|
258 |
|
259 JSObject* |
|
260 nsMimeType::WrapObject(JSContext* aCx) |
|
261 { |
|
262 return MimeTypeBinding::Wrap(aCx, this); |
|
263 } |
|
264 |
|
265 void |
|
266 nsMimeType::GetDescription(nsString& retval) const |
|
267 { |
|
268 retval.Truncate(); |
|
269 |
|
270 if (mPluginElement) { |
|
271 CopyUTF8toUTF16(mPluginElement->PluginTag()-> |
|
272 mMimeDescriptions[mPluginTagMimeIndex], retval); |
|
273 } |
|
274 } |
|
275 |
|
276 nsPluginElement* |
|
277 nsMimeType::GetEnabledPlugin() const |
|
278 { |
|
279 return (mPluginElement && mPluginElement->PluginTag()->IsEnabled()) ? |
|
280 mPluginElement : nullptr; |
|
281 } |
|
282 |
|
283 void |
|
284 nsMimeType::GetSuffixes(nsString& retval) const |
|
285 { |
|
286 retval.Truncate(); |
|
287 |
|
288 if (mPluginElement) { |
|
289 CopyUTF8toUTF16(mPluginElement->PluginTag()-> |
|
290 mExtensions[mPluginTagMimeIndex], retval); |
|
291 } |
|
292 } |
|
293 |
|
294 void |
|
295 nsMimeType::GetType(nsString& aRetval) const |
|
296 { |
|
297 aRetval = mType; |
|
298 } |