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
)
39 nsMimeTypeArray::~nsMimeTypeArray()
44 nsMimeTypeArray::WrapObject(JSContext
* aCx
)
46 return MimeTypeArrayBinding::Wrap(aCx
, this);
50 nsMimeTypeArray::Refresh()
53 mHiddenMimeTypes
.Clear();
57 nsMimeTypeArray::GetParentObject() const
64 nsMimeTypeArray::Item(uint32_t aIndex
)
67 return IndexedGetter(aIndex
, unused
);
71 nsMimeTypeArray::NamedItem(const nsAString
& aName
)
74 return NamedGetter(aName
, unused
);
78 nsMimeTypeArray::IndexedGetter(uint32_t aIndex
, bool &aFound
)
82 EnsurePluginMimeTypes();
84 if (aIndex
>= mMimeTypes
.Length()) {
90 return mMimeTypes
[aIndex
];
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())) {
108 nsMimeTypeArray::NamedGetter(const nsAString
& aName
, bool &aFound
)
112 EnsurePluginMimeTypes();
114 nsString
lowerName(aName
);
115 ToLowerCase(lowerName
);
117 nsMimeType
* mimeType
= FindMimeType(mMimeTypes
, lowerName
);
119 mimeType
= FindMimeType(mHiddenMimeTypes
, lowerName
);
127 // Now let's check with the MIME service.
128 nsCOMPtr
<nsIMIMEService
> mimeSrv
= do_GetService("@mozilla.org/mime;1");
133 nsCOMPtr
<nsIMIMEInfo
> mimeInfo
;
134 mimeSrv
->GetFromTypeAndExtension(NS_ConvertUTF16toUTF8(lowerName
),
135 EmptyCString(), getter_AddRefs(mimeInfo
));
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
);
148 nsCOMPtr
<nsIHandlerApp
> helper
;
149 mimeInfo
->GetPreferredApplicationHandler(getter_AddRefs(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
165 // If we got here, we support this type! Say so.
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
);
177 nsMimeTypeArray::NameIsEnumerable(const nsAString
& aName
)
183 nsMimeTypeArray::Length()
185 EnsurePluginMimeTypes();
187 return mMimeTypes
.Length();
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());
201 nsMimeTypeArray::EnsurePluginMimeTypes()
203 if (!mMimeTypes
.IsEmpty() || !mHiddenMimeTypes
.IsEmpty() || !mWindow
) {
207 nsCOMPtr
<nsIDOMNavigator
> navigator
;
208 mWindow
->GetNavigator(getter_AddRefs(navigator
));
215 nsPluginArray
*pluginArray
=
216 static_cast<Navigator
*>(navigator
.get())->GetPlugins(rv
);
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
)
232 mPluginElement(aPluginElement
),
233 mPluginTagMimeIndex(aPluginTagMimeIndex
),
239 nsMimeType::nsMimeType(nsPIDOMWindow
* aWindow
, const nsAString
& aType
)
241 mPluginElement(nullptr),
242 mPluginTagMimeIndex(0),
248 nsMimeType::~nsMimeType()
253 nsMimeType::GetParentObject() const
260 nsMimeType::WrapObject(JSContext
* aCx
)
262 return MimeTypeBinding::Wrap(aCx
, this);
266 nsMimeType::GetDescription(nsString
& retval
) const
270 if (mPluginElement
) {
271 CopyUTF8toUTF16(mPluginElement
->PluginTag()->
272 mMimeDescriptions
[mPluginTagMimeIndex
], retval
);
277 nsMimeType::GetEnabledPlugin() const
279 return (mPluginElement
&& mPluginElement
->PluginTag()->IsEnabled()) ?
280 mPluginElement
: nullptr;
284 nsMimeType::GetSuffixes(nsString
& retval
) const
288 if (mPluginElement
) {
289 CopyUTF8toUTF16(mPluginElement
->PluginTag()->
290 mExtensions
[mPluginTagMimeIndex
], retval
);
295 nsMimeType::GetType(nsString
& aRetval
) const