1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/base/nsMimeTypeArray.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,298 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 sw=2 et tw=79: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "nsMimeTypeArray.h" 1.11 + 1.12 +#include "mozilla/dom/MimeTypeArrayBinding.h" 1.13 +#include "mozilla/dom/MimeTypeBinding.h" 1.14 +#include "nsIDOMNavigator.h" 1.15 +#include "nsPluginArray.h" 1.16 +#include "nsIMIMEService.h" 1.17 +#include "nsIMIMEInfo.h" 1.18 +#include "Navigator.h" 1.19 +#include "nsServiceManagerUtils.h" 1.20 + 1.21 +using namespace mozilla; 1.22 +using namespace mozilla::dom; 1.23 + 1.24 +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsMimeTypeArray) 1.25 +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsMimeTypeArray) 1.26 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsMimeTypeArray) 1.27 + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 1.28 + NS_INTERFACE_MAP_ENTRY(nsISupports) 1.29 +NS_INTERFACE_MAP_END 1.30 + 1.31 +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(nsMimeTypeArray, 1.32 + mWindow, 1.33 + mMimeTypes, 1.34 + mHiddenMimeTypes) 1.35 + 1.36 +nsMimeTypeArray::nsMimeTypeArray(nsPIDOMWindow* aWindow) 1.37 + : mWindow(aWindow) 1.38 +{ 1.39 + SetIsDOMBinding(); 1.40 +} 1.41 + 1.42 +nsMimeTypeArray::~nsMimeTypeArray() 1.43 +{ 1.44 +} 1.45 + 1.46 +JSObject* 1.47 +nsMimeTypeArray::WrapObject(JSContext* aCx) 1.48 +{ 1.49 + return MimeTypeArrayBinding::Wrap(aCx, this); 1.50 +} 1.51 + 1.52 +void 1.53 +nsMimeTypeArray::Refresh() 1.54 +{ 1.55 + mMimeTypes.Clear(); 1.56 + mHiddenMimeTypes.Clear(); 1.57 +} 1.58 + 1.59 +nsPIDOMWindow* 1.60 +nsMimeTypeArray::GetParentObject() const 1.61 +{ 1.62 + MOZ_ASSERT(mWindow); 1.63 + return mWindow; 1.64 +} 1.65 + 1.66 +nsMimeType* 1.67 +nsMimeTypeArray::Item(uint32_t aIndex) 1.68 +{ 1.69 + bool unused; 1.70 + return IndexedGetter(aIndex, unused); 1.71 +} 1.72 + 1.73 +nsMimeType* 1.74 +nsMimeTypeArray::NamedItem(const nsAString& aName) 1.75 +{ 1.76 + bool unused; 1.77 + return NamedGetter(aName, unused); 1.78 +} 1.79 + 1.80 +nsMimeType* 1.81 +nsMimeTypeArray::IndexedGetter(uint32_t aIndex, bool &aFound) 1.82 +{ 1.83 + aFound = false; 1.84 + 1.85 + EnsurePluginMimeTypes(); 1.86 + 1.87 + if (aIndex >= mMimeTypes.Length()) { 1.88 + return nullptr; 1.89 + } 1.90 + 1.91 + aFound = true; 1.92 + 1.93 + return mMimeTypes[aIndex]; 1.94 +} 1.95 + 1.96 +static nsMimeType* 1.97 +FindMimeType(const nsTArray<nsRefPtr<nsMimeType> >& aMimeTypes, 1.98 + const nsAString& aType) 1.99 +{ 1.100 + for (uint32_t i = 0; i < aMimeTypes.Length(); ++i) { 1.101 + nsMimeType* mimeType = aMimeTypes[i]; 1.102 + if (aType.Equals(mimeType->Type())) { 1.103 + return mimeType; 1.104 + } 1.105 + } 1.106 + 1.107 + return nullptr; 1.108 +} 1.109 + 1.110 +nsMimeType* 1.111 +nsMimeTypeArray::NamedGetter(const nsAString& aName, bool &aFound) 1.112 +{ 1.113 + aFound = false; 1.114 + 1.115 + EnsurePluginMimeTypes(); 1.116 + 1.117 + nsString lowerName(aName); 1.118 + ToLowerCase(lowerName); 1.119 + 1.120 + nsMimeType* mimeType = FindMimeType(mMimeTypes, lowerName); 1.121 + if (!mimeType) { 1.122 + mimeType = FindMimeType(mHiddenMimeTypes, lowerName); 1.123 + } 1.124 + 1.125 + if (mimeType) { 1.126 + aFound = true; 1.127 + return mimeType; 1.128 + } 1.129 + 1.130 + // Now let's check with the MIME service. 1.131 + nsCOMPtr<nsIMIMEService> mimeSrv = do_GetService("@mozilla.org/mime;1"); 1.132 + if (!mimeSrv) { 1.133 + return nullptr; 1.134 + } 1.135 + 1.136 + nsCOMPtr<nsIMIMEInfo> mimeInfo; 1.137 + mimeSrv->GetFromTypeAndExtension(NS_ConvertUTF16toUTF8(lowerName), 1.138 + EmptyCString(), getter_AddRefs(mimeInfo)); 1.139 + if (!mimeInfo) { 1.140 + return nullptr; 1.141 + } 1.142 + 1.143 + // Now we check whether we can really claim to support this type 1.144 + nsHandlerInfoAction action = nsIHandlerInfo::saveToDisk; 1.145 + mimeInfo->GetPreferredAction(&action); 1.146 + if (action != nsIMIMEInfo::handleInternally) { 1.147 + bool hasHelper = false; 1.148 + mimeInfo->GetHasDefaultHandler(&hasHelper); 1.149 + 1.150 + if (!hasHelper) { 1.151 + nsCOMPtr<nsIHandlerApp> helper; 1.152 + mimeInfo->GetPreferredApplicationHandler(getter_AddRefs(helper)); 1.153 + 1.154 + if (!helper) { 1.155 + // mime info from the OS may not have a PreferredApplicationHandler 1.156 + // so just check for an empty default description 1.157 + nsAutoString defaultDescription; 1.158 + mimeInfo->GetDefaultDescription(defaultDescription); 1.159 + 1.160 + if (defaultDescription.IsEmpty()) { 1.161 + // no support; just leave 1.162 + return nullptr; 1.163 + } 1.164 + } 1.165 + } 1.166 + } 1.167 + 1.168 + // If we got here, we support this type! Say so. 1.169 + aFound = true; 1.170 + 1.171 + // We don't want navigator.mimeTypes enumeration to expose MIME types with 1.172 + // application handlers, so add them to the list of hidden MIME types. 1.173 + nsMimeType *mt = new nsMimeType(mWindow, lowerName); 1.174 + mHiddenMimeTypes.AppendElement(mt); 1.175 + 1.176 + return mt; 1.177 +} 1.178 + 1.179 +bool 1.180 +nsMimeTypeArray::NameIsEnumerable(const nsAString& aName) 1.181 +{ 1.182 + return true; 1.183 +} 1.184 + 1.185 +uint32_t 1.186 +nsMimeTypeArray::Length() 1.187 +{ 1.188 + EnsurePluginMimeTypes(); 1.189 + 1.190 + return mMimeTypes.Length(); 1.191 +} 1.192 + 1.193 +void 1.194 +nsMimeTypeArray::GetSupportedNames(unsigned, nsTArray< nsString >& aRetval) 1.195 +{ 1.196 + EnsurePluginMimeTypes(); 1.197 + 1.198 + for (uint32_t i = 0; i < mMimeTypes.Length(); ++i) { 1.199 + aRetval.AppendElement(mMimeTypes[i]->Type()); 1.200 + } 1.201 +} 1.202 + 1.203 +void 1.204 +nsMimeTypeArray::EnsurePluginMimeTypes() 1.205 +{ 1.206 + if (!mMimeTypes.IsEmpty() || !mHiddenMimeTypes.IsEmpty() || !mWindow) { 1.207 + return; 1.208 + } 1.209 + 1.210 + nsCOMPtr<nsIDOMNavigator> navigator; 1.211 + mWindow->GetNavigator(getter_AddRefs(navigator)); 1.212 + 1.213 + if (!navigator) { 1.214 + return; 1.215 + } 1.216 + 1.217 + ErrorResult rv; 1.218 + nsPluginArray *pluginArray = 1.219 + static_cast<Navigator*>(navigator.get())->GetPlugins(rv); 1.220 + if (!pluginArray) { 1.221 + return; 1.222 + } 1.223 + 1.224 + pluginArray->GetMimeTypes(mMimeTypes, mHiddenMimeTypes); 1.225 +} 1.226 + 1.227 +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsMimeType, AddRef) 1.228 +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsMimeType, Release) 1.229 + 1.230 +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(nsMimeType, mWindow, mPluginElement) 1.231 + 1.232 +nsMimeType::nsMimeType(nsPIDOMWindow* aWindow, nsPluginElement* aPluginElement, 1.233 + uint32_t aPluginTagMimeIndex, const nsAString& aType) 1.234 + : mWindow(aWindow), 1.235 + mPluginElement(aPluginElement), 1.236 + mPluginTagMimeIndex(aPluginTagMimeIndex), 1.237 + mType(aType) 1.238 +{ 1.239 + SetIsDOMBinding(); 1.240 +} 1.241 + 1.242 +nsMimeType::nsMimeType(nsPIDOMWindow* aWindow, const nsAString& aType) 1.243 + : mWindow(aWindow), 1.244 + mPluginElement(nullptr), 1.245 + mPluginTagMimeIndex(0), 1.246 + mType(aType) 1.247 +{ 1.248 + SetIsDOMBinding(); 1.249 +} 1.250 + 1.251 +nsMimeType::~nsMimeType() 1.252 +{ 1.253 +} 1.254 + 1.255 +nsPIDOMWindow* 1.256 +nsMimeType::GetParentObject() const 1.257 +{ 1.258 + MOZ_ASSERT(mWindow); 1.259 + return mWindow; 1.260 +} 1.261 + 1.262 +JSObject* 1.263 +nsMimeType::WrapObject(JSContext* aCx) 1.264 +{ 1.265 + return MimeTypeBinding::Wrap(aCx, this); 1.266 +} 1.267 + 1.268 +void 1.269 +nsMimeType::GetDescription(nsString& retval) const 1.270 +{ 1.271 + retval.Truncate(); 1.272 + 1.273 + if (mPluginElement) { 1.274 + CopyUTF8toUTF16(mPluginElement->PluginTag()-> 1.275 + mMimeDescriptions[mPluginTagMimeIndex], retval); 1.276 + } 1.277 +} 1.278 + 1.279 +nsPluginElement* 1.280 +nsMimeType::GetEnabledPlugin() const 1.281 +{ 1.282 + return (mPluginElement && mPluginElement->PluginTag()->IsEnabled()) ? 1.283 + mPluginElement : nullptr; 1.284 +} 1.285 + 1.286 +void 1.287 +nsMimeType::GetSuffixes(nsString& retval) const 1.288 +{ 1.289 + retval.Truncate(); 1.290 + 1.291 + if (mPluginElement) { 1.292 + CopyUTF8toUTF16(mPluginElement->PluginTag()-> 1.293 + mExtensions[mPluginTagMimeIndex], retval); 1.294 + } 1.295 +} 1.296 + 1.297 +void 1.298 +nsMimeType::GetType(nsString& aRetval) const 1.299 +{ 1.300 + aRetval = mType; 1.301 +}