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 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is mozilla.org code.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
24 * Pierre Phaneuf <pp@ludusdesign.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #include "nsMimeTypeArray.h"
41 #include "nsContentUtils.h"
42 #include "nsIScriptGlobalObject.h"
43 #include "nsIDOMNavigator.h"
44 #include "nsIDOMPluginArray.h"
45 #include "nsIDOMPlugin.h"
46 #include "nsDOMClassInfo.h"
47 #include "nsIMIMEService.h"
48 #include "nsIMIMEInfo.h"
52 nsMimeTypeArray::nsMimeTypeArray(nsIDOMNavigator
* navigator
)
53 : mNavigator(navigator
),
54 mPluginMimeTypeCount(0),
59 nsMimeTypeArray::~nsMimeTypeArray()
65 DOMCI_DATA(MimeTypeArray
, nsMimeTypeArray
)
67 // QueryInterface implementation for nsMimeTypeArray
68 NS_INTERFACE_MAP_BEGIN(nsMimeTypeArray
)
69 NS_INTERFACE_MAP_ENTRY(nsISupports
)
70 NS_INTERFACE_MAP_ENTRY(nsIDOMMimeTypeArray
)
71 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MimeTypeArray
)
75 NS_IMPL_ADDREF(nsMimeTypeArray
)
76 NS_IMPL_RELEASE(nsMimeTypeArray
)
80 nsMimeTypeArray::GetLength(PRUint32
* aLength
)
83 nsresult rv
= GetMimeTypes();
88 NS_ASSERTION(mPluginMimeTypeCount
<= (PRUint32
)mMimeTypeArray
.Count(),
89 "The number of total mimetypes should be equal to or higher "
90 "than the number of plugin mimetypes.");
92 *aLength
= mPluginMimeTypeCount
;
97 nsMimeTypeArray::GetItemAt(PRUint32 aIndex
, nsresult
*aResult
)
100 *aResult
= GetMimeTypes();
101 if (*aResult
!= NS_OK
)
105 NS_ASSERTION(mPluginMimeTypeCount
<= (PRUint32
)mMimeTypeArray
.Count(),
106 "The number of total mimetypes should be equal to or higher "
107 "than the number of plugin mimetypes.");
109 if (aIndex
>= mPluginMimeTypeCount
) {
110 *aResult
= NS_ERROR_FAILURE
;
117 return mMimeTypeArray
[aIndex
];
121 nsMimeTypeArray::Item(PRUint32 aIndex
, nsIDOMMimeType
** aReturn
)
125 NS_IF_ADDREF(*aReturn
= GetItemAt(aIndex
, &rv
));
131 nsMimeTypeArray::GetNamedItem(const nsAString
& aName
, nsresult
* aResult
)
134 *aResult
= GetMimeTypes();
135 if (*aResult
!= NS_OK
)
139 NS_ASSERTION(mPluginMimeTypeCount
<= (PRUint32
)mMimeTypeArray
.Count(),
140 "The number of total mimetypes should be equal to or higher "
141 "than the number of plugin mimetypes.");
147 for (PRInt32 i
= 0; i
< mMimeTypeArray
.Count(); i
++) {
148 nsIDOMMimeType
*mtype
= mMimeTypeArray
[i
];
150 mtype
->GetType(type
);
152 if (type
.Equals(aName
)) {
157 // Now let's check with the MIME service.
158 nsCOMPtr
<nsIMIMEService
> mimeSrv
= do_GetService("@mozilla.org/mime;1");
160 nsCOMPtr
<nsIMIMEInfo
> mimeInfo
;
161 mimeSrv
->GetFromTypeAndExtension(NS_ConvertUTF16toUTF8(aName
), EmptyCString(),
162 getter_AddRefs(mimeInfo
));
164 // Now we check whether we can really claim to support this type
165 nsHandlerInfoAction action
= nsIHandlerInfo::saveToDisk
;
166 mimeInfo
->GetPreferredAction(&action
);
167 if (action
!= nsIMIMEInfo::handleInternally
) {
168 PRBool hasHelper
= PR_FALSE
;
169 mimeInfo
->GetHasDefaultHandler(&hasHelper
);
171 nsCOMPtr
<nsIHandlerApp
> helper
;
172 mimeInfo
->GetPreferredApplicationHandler(getter_AddRefs(helper
));
174 // mime info from the OS may not have a PreferredApplicationHandler
175 // so just check for an empty default description
176 nsAutoString defaultDescription
;
177 mimeInfo
->GetDefaultDescription(defaultDescription
);
178 if (defaultDescription
.IsEmpty()) {
179 // no support; just leave
186 // If we got here, we support this type! Say so.
187 nsCOMPtr
<nsIDOMMimeType
> helper
, entry
;
188 if (!(helper
= new nsHelperMimeType(aName
)) ||
189 !(entry
= new nsMimeType(nsnull
, helper
)) ||
190 !mMimeTypeArray
.AppendObject(entry
)) {
191 *aResult
= NS_ERROR_OUT_OF_MEMORY
;
204 nsMimeTypeArray::NamedItem(const nsAString
& aName
, nsIDOMMimeType
** aReturn
)
208 NS_IF_ADDREF(*aReturn
= GetNamedItem(aName
, &rv
));
213 void nsMimeTypeArray::Clear()
216 mMimeTypeArray
.Clear();
217 mPluginMimeTypeCount
= 0;
220 nsresult
nsMimeTypeArray::Refresh()
223 return GetMimeTypes();
226 nsresult
nsMimeTypeArray::GetMimeTypes()
228 NS_PRECONDITION(!mInited
&& mPluginMimeTypeCount
==0,
229 "already initialized");
232 return NS_ERROR_NOT_AVAILABLE
;
235 nsIDOMPluginArray
* pluginArray
= nsnull
;
236 nsresult rv
= mNavigator
->GetPlugins(&pluginArray
);
238 // count up all possible MimeTypes, and collect them here. Later,
239 // we'll remove duplicates.
240 PRUint32 pluginMimeTypeCount
= 0;
241 PRUint32 pluginCount
= 0;
242 rv
= pluginArray
->GetLength(&pluginCount
);
245 for (i
= 0; i
< pluginCount
; i
++) {
246 nsCOMPtr
<nsIDOMPlugin
> plugin
;
247 if (NS_SUCCEEDED(pluginArray
->Item(i
, getter_AddRefs(plugin
))) &&
249 PRUint32 mimeTypeCount
= 0;
250 if (plugin
->GetLength(&mimeTypeCount
) == NS_OK
)
251 pluginMimeTypeCount
+= mimeTypeCount
;
254 // now we know how many there are, start gathering them.
255 if (!mMimeTypeArray
.SetCapacity(pluginMimeTypeCount
))
256 return NS_ERROR_OUT_OF_MEMORY
;
258 mPluginMimeTypeCount
= pluginMimeTypeCount
;
262 for (k
= 0; k
< pluginCount
; k
++) {
263 nsCOMPtr
<nsIDOMPlugin
> plugin
;
264 if (NS_SUCCEEDED(pluginArray
->Item(k
, getter_AddRefs(plugin
))) &&
266 PRUint32 mimeTypeCount
= 0;
267 if (plugin
->GetLength(&mimeTypeCount
) == NS_OK
) {
268 nsCOMPtr
<nsIDOMMimeType
> item
;
269 for (PRUint32 j
= 0; j
< mimeTypeCount
; j
++) {
270 plugin
->Item(j
, getter_AddRefs(item
));
271 mMimeTypeArray
.AppendObject(item
);
277 NS_RELEASE(pluginArray
);
282 nsMimeType::nsMimeType(nsIDOMPlugin
* aPlugin
, nsIDOMMimeType
* aMimeType
)
285 mMimeType
= aMimeType
;
288 nsMimeType::~nsMimeType()
293 DOMCI_DATA(MimeType
, nsMimeType
)
295 // QueryInterface implementation for nsMimeType
296 NS_INTERFACE_MAP_BEGIN(nsMimeType
)
297 NS_INTERFACE_MAP_ENTRY(nsISupports
)
298 NS_INTERFACE_MAP_ENTRY(nsIDOMMimeType
)
299 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MimeType
)
303 NS_IMPL_ADDREF(nsMimeType
)
304 NS_IMPL_RELEASE(nsMimeType
)
308 nsMimeType::GetDescription(nsAString
& aDescription
)
310 return mMimeType
->GetDescription(aDescription
);
314 nsMimeType::GetEnabledPlugin(nsIDOMPlugin
** aEnabledPlugin
)
319 *aEnabledPlugin
= mPlugin
;
321 NS_IF_ADDREF(*aEnabledPlugin
);
327 nsMimeType::GetSuffixes(nsAString
& aSuffixes
)
329 return mMimeType
->GetSuffixes(aSuffixes
);
333 nsMimeType::GetType(nsAString
& aType
)
335 return mMimeType
->GetType(aType
);
338 // QueryInterface implementation for nsHelperMimeType
339 NS_IMPL_ISUPPORTS1(nsHelperMimeType
, nsIDOMMimeType
)
342 nsHelperMimeType::GetDescription(nsAString
& aDescription
)
344 aDescription
.Truncate();
349 nsHelperMimeType::GetEnabledPlugin(nsIDOMPlugin
** aEnabledPlugin
)
351 *aEnabledPlugin
= nsnull
;
356 nsHelperMimeType::GetSuffixes(nsAString
& aSuffixes
)
358 aSuffixes
.Truncate();
363 nsHelperMimeType::GetType(nsAString
& aType
)