Bumping manifests a=b2g-bump
[gecko.git] / dom / base / nsMimeTypeArray.cpp
blobfaef9a0135e05b4865cafff3430476bce348d97e
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/. */
7 #include "nsMimeTypeArray.h"
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"
18 using namespace mozilla;
19 using namespace mozilla::dom;
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
28 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsMimeTypeArray,
29 mWindow,
30 mMimeTypes,
31 mHiddenMimeTypes)
33 nsMimeTypeArray::nsMimeTypeArray(nsPIDOMWindow* aWindow)
34 : mWindow(aWindow)
36 SetIsDOMBinding();
39 nsMimeTypeArray::~nsMimeTypeArray()
43 JSObject*
44 nsMimeTypeArray::WrapObject(JSContext* aCx)
46 return MimeTypeArrayBinding::Wrap(aCx, this);
49 void
50 nsMimeTypeArray::Refresh()
52 mMimeTypes.Clear();
53 mHiddenMimeTypes.Clear();
56 nsPIDOMWindow*
57 nsMimeTypeArray::GetParentObject() const
59 MOZ_ASSERT(mWindow);
60 return mWindow;
63 nsMimeType*
64 nsMimeTypeArray::Item(uint32_t aIndex)
66 bool unused;
67 return IndexedGetter(aIndex, unused);
70 nsMimeType*
71 nsMimeTypeArray::NamedItem(const nsAString& aName)
73 bool unused;
74 return NamedGetter(aName, unused);
77 nsMimeType*
78 nsMimeTypeArray::IndexedGetter(uint32_t aIndex, bool &aFound)
80 aFound = false;
82 EnsurePluginMimeTypes();
84 if (aIndex >= mMimeTypes.Length()) {
85 return nullptr;
88 aFound = true;
90 return mMimeTypes[aIndex];
93 static nsMimeType*
94 FindMimeType(const nsTArray<nsRefPtr<nsMimeType> >& aMimeTypes,
95 const nsAString& aType)
97 for (uint32_t i = 0; i < aMimeTypes.Length(); ++i) {
98 nsMimeType* mimeType = aMimeTypes[i];
99 if (aType.Equals(mimeType->Type())) {
100 return mimeType;
104 return nullptr;
107 nsMimeType*
108 nsMimeTypeArray::NamedGetter(const nsAString& aName, bool &aFound)
110 aFound = false;
112 EnsurePluginMimeTypes();
114 nsString lowerName(aName);
115 ToLowerCase(lowerName);
117 nsMimeType* mimeType = FindMimeType(mMimeTypes, lowerName);
118 if (!mimeType) {
119 mimeType = FindMimeType(mHiddenMimeTypes, lowerName);
122 if (mimeType) {
123 aFound = true;
124 return mimeType;
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;
133 nsCOMPtr<nsIMIMEInfo> mimeInfo;
134 mimeSrv->GetFromTypeAndExtension(NS_ConvertUTF16toUTF8(lowerName),
135 EmptyCString(), getter_AddRefs(mimeInfo));
136 if (!mimeInfo) {
137 return nullptr;
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);
147 if (!hasHelper) {
148 nsCOMPtr<nsIHandlerApp> helper;
149 mimeInfo->GetPreferredApplicationHandler(getter_AddRefs(helper));
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);
157 if (defaultDescription.IsEmpty()) {
158 // no support; just leave
159 return nullptr;
165 // If we got here, we support this type! Say so.
166 aFound = true;
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);
173 return mt;
176 bool
177 nsMimeTypeArray::NameIsEnumerable(const nsAString& aName)
179 return true;
182 uint32_t
183 nsMimeTypeArray::Length()
185 EnsurePluginMimeTypes();
187 return mMimeTypes.Length();
190 void
191 nsMimeTypeArray::GetSupportedNames(unsigned, nsTArray< nsString >& aRetval)
193 EnsurePluginMimeTypes();
195 for (uint32_t i = 0; i < mMimeTypes.Length(); ++i) {
196 aRetval.AppendElement(mMimeTypes[i]->Type());
200 void
201 nsMimeTypeArray::EnsurePluginMimeTypes()
203 if (!mMimeTypes.IsEmpty() || !mHiddenMimeTypes.IsEmpty() || !mWindow) {
204 return;
207 nsCOMPtr<nsIDOMNavigator> navigator;
208 mWindow->GetNavigator(getter_AddRefs(navigator));
210 if (!navigator) {
211 return;
214 ErrorResult rv;
215 nsPluginArray *pluginArray =
216 static_cast<Navigator*>(navigator.get())->GetPlugins(rv);
217 if (!pluginArray) {
218 return;
221 pluginArray->GetMimeTypes(mMimeTypes, mHiddenMimeTypes);
224 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsMimeType, AddRef)
225 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsMimeType, Release)
227 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsMimeType, mWindow, mPluginElement)
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)
236 SetIsDOMBinding();
239 nsMimeType::nsMimeType(nsPIDOMWindow* aWindow, const nsAString& aType)
240 : mWindow(aWindow),
241 mPluginElement(nullptr),
242 mPluginTagMimeIndex(0),
243 mType(aType)
245 SetIsDOMBinding();
248 nsMimeType::~nsMimeType()
252 nsPIDOMWindow*
253 nsMimeType::GetParentObject() const
255 MOZ_ASSERT(mWindow);
256 return mWindow;
259 JSObject*
260 nsMimeType::WrapObject(JSContext* aCx)
262 return MimeTypeBinding::Wrap(aCx, this);
265 void
266 nsMimeType::GetDescription(nsString& retval) const
268 retval.Truncate();
270 if (mPluginElement) {
271 CopyUTF8toUTF16(mPluginElement->PluginTag()->
272 mMimeDescriptions[mPluginTagMimeIndex], retval);
276 nsPluginElement*
277 nsMimeType::GetEnabledPlugin() const
279 return (mPluginElement && mPluginElement->PluginTag()->IsEnabled()) ?
280 mPluginElement : nullptr;
283 void
284 nsMimeType::GetSuffixes(nsString& retval) const
286 retval.Truncate();
288 if (mPluginElement) {
289 CopyUTF8toUTF16(mPluginElement->PluginTag()->
290 mExtensions[mPluginTagMimeIndex], retval);
294 void
295 nsMimeType::GetType(nsString& aRetval) const
297 aRetval = mType;