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
)
28 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsMimeTypeArray
,
33 nsMimeTypeArray::nsMimeTypeArray(nsPIDOMWindow
* aWindow
)
38 nsMimeTypeArray::~nsMimeTypeArray()
43 nsMimeTypeArray::WrapObject(JSContext
* aCx
)
45 return MimeTypeArrayBinding::Wrap(aCx
, this);
49 nsMimeTypeArray::Refresh()
52 mHiddenMimeTypes
.Clear();
56 nsMimeTypeArray::GetParentObject() const
63 nsMimeTypeArray::Item(uint32_t aIndex
)
66 return IndexedGetter(aIndex
, unused
);
70 nsMimeTypeArray::NamedItem(const nsAString
& aName
)
73 return NamedGetter(aName
, unused
);
77 nsMimeTypeArray::IndexedGetter(uint32_t aIndex
, bool &aFound
)
81 EnsurePluginMimeTypes();
83 if (aIndex
>= mMimeTypes
.Length()) {
89 return mMimeTypes
[aIndex
];
93 FindMimeType(const nsTArray
<nsRefPtr
<nsMimeType
> >& aMimeTypes
,
94 const nsAString
& aType
)
96 for (uint32_t i
= 0; i
< aMimeTypes
.Length(); ++i
) {
97 nsMimeType
* mimeType
= aMimeTypes
[i
];
98 if (aType
.Equals(mimeType
->Type())) {
107 nsMimeTypeArray::NamedGetter(const nsAString
& aName
, bool &aFound
)
111 EnsurePluginMimeTypes();
113 nsString
lowerName(aName
);
114 ToLowerCase(lowerName
);
116 nsMimeType
* mimeType
= FindMimeType(mMimeTypes
, lowerName
);
118 mimeType
= FindMimeType(mHiddenMimeTypes
, lowerName
);
126 // Now let's check with the MIME service.
127 nsCOMPtr
<nsIMIMEService
> mimeSrv
= do_GetService("@mozilla.org/mime;1");
132 nsCOMPtr
<nsIMIMEInfo
> mimeInfo
;
133 mimeSrv
->GetFromTypeAndExtension(NS_ConvertUTF16toUTF8(lowerName
),
134 EmptyCString(), getter_AddRefs(mimeInfo
));
139 // Now we check whether we can really claim to support this type
140 nsHandlerInfoAction action
= nsIHandlerInfo::saveToDisk
;
141 mimeInfo
->GetPreferredAction(&action
);
142 if (action
!= nsIMIMEInfo::handleInternally
) {
143 bool hasHelper
= false;
144 mimeInfo
->GetHasDefaultHandler(&hasHelper
);
147 nsCOMPtr
<nsIHandlerApp
> helper
;
148 mimeInfo
->GetPreferredApplicationHandler(getter_AddRefs(helper
));
151 // mime info from the OS may not have a PreferredApplicationHandler
152 // so just check for an empty default description
153 nsAutoString defaultDescription
;
154 mimeInfo
->GetDefaultDescription(defaultDescription
);
156 if (defaultDescription
.IsEmpty()) {
157 // no support; just leave
164 // If we got here, we support this type! Say so.
167 // We don't want navigator.mimeTypes enumeration to expose MIME types with
168 // application handlers, so add them to the list of hidden MIME types.
169 nsMimeType
*mt
= new nsMimeType(mWindow
, lowerName
);
170 mHiddenMimeTypes
.AppendElement(mt
);
176 nsMimeTypeArray::NameIsEnumerable(const nsAString
& aName
)
182 nsMimeTypeArray::Length()
184 EnsurePluginMimeTypes();
186 return mMimeTypes
.Length();
190 nsMimeTypeArray::GetSupportedNames(unsigned, nsTArray
< nsString
>& aRetval
)
192 EnsurePluginMimeTypes();
194 for (uint32_t i
= 0; i
< mMimeTypes
.Length(); ++i
) {
195 aRetval
.AppendElement(mMimeTypes
[i
]->Type());
200 nsMimeTypeArray::EnsurePluginMimeTypes()
202 if (!mMimeTypes
.IsEmpty() || !mHiddenMimeTypes
.IsEmpty() || !mWindow
) {
206 nsCOMPtr
<nsIDOMNavigator
> navigator
;
207 mWindow
->GetNavigator(getter_AddRefs(navigator
));
214 nsPluginArray
*pluginArray
=
215 static_cast<Navigator
*>(navigator
.get())->GetPlugins(rv
);
220 pluginArray
->GetMimeTypes(mMimeTypes
, mHiddenMimeTypes
);
223 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsMimeType
, AddRef
)
224 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsMimeType
, Release
)
226 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsMimeType
, mWindow
, mPluginElement
)
228 nsMimeType::nsMimeType(nsPIDOMWindow
* aWindow
, nsPluginElement
* aPluginElement
,
229 uint32_t aPluginTagMimeIndex
, const nsAString
& aType
)
231 mPluginElement(aPluginElement
),
232 mPluginTagMimeIndex(aPluginTagMimeIndex
),
237 nsMimeType::nsMimeType(nsPIDOMWindow
* aWindow
, const nsAString
& aType
)
239 mPluginElement(nullptr),
240 mPluginTagMimeIndex(0),
245 nsMimeType::~nsMimeType()
250 nsMimeType::GetParentObject() const
257 nsMimeType::WrapObject(JSContext
* aCx
)
259 return MimeTypeBinding::Wrap(aCx
, this);
263 nsMimeType::GetDescription(nsString
& retval
) const
267 if (mPluginElement
) {
268 CopyUTF8toUTF16(mPluginElement
->PluginTag()->
269 mMimeDescriptions
[mPluginTagMimeIndex
], retval
);
274 nsMimeType::GetEnabledPlugin() const
276 return (mPluginElement
&& mPluginElement
->PluginTag()->IsEnabled()) ?
277 mPluginElement
: nullptr;
281 nsMimeType::GetSuffixes(nsString
& retval
) const
285 if (mPluginElement
) {
286 CopyUTF8toUTF16(mPluginElement
->PluginTag()->
287 mExtensions
[mPluginTagMimeIndex
], retval
);
292 nsMimeType::GetType(nsString
& aRetval
) const