dom/base/nsMimeTypeArray.cpp

changeset 0
6474c204b198
     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 +}

mercurial