Blame docshell/base/nsWebNavigationInfo.cpp

Packit f0b94e
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit f0b94e
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#include "nsWebNavigationInfo.h"
Packit f0b94e
#include "nsIWebNavigation.h"
Packit f0b94e
#include "nsServiceManagerUtils.h"
Packit f0b94e
#include "nsIDocumentLoaderFactory.h"
Packit f0b94e
#include "nsIPluginHost.h"
Packit f0b94e
#include "nsIDocShell.h"
Packit f0b94e
#include "nsContentUtils.h"
Packit f0b94e
#include "imgLoader.h"
Packit f0b94e
#include "nsPluginHost.h"
Packit f0b94e
Packit f0b94e
NS_IMPL_ISUPPORTS(nsWebNavigationInfo, nsIWebNavigationInfo)
Packit f0b94e
Packit f0b94e
nsresult nsWebNavigationInfo::Init() {
Packit f0b94e
  nsresult rv;
Packit f0b94e
  mCategoryManager = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv;;
Packit f0b94e
  NS_ENSURE_SUCCESS(rv, rv);
Packit f0b94e
Packit f0b94e
  return NS_OK;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
NS_IMETHODIMP
Packit f0b94e
nsWebNavigationInfo::IsTypeSupported(const nsACString& aType,
Packit f0b94e
                                     nsIWebNavigation* aWebNav,
Packit f0b94e
                                     uint32_t* aIsTypeSupported) {
Packit f0b94e
  NS_PRECONDITION(aIsTypeSupported, "null out param?");
Packit f0b94e
Packit f0b94e
  // Note to self: aWebNav could be an nsWebBrowser or an nsDocShell here (or
Packit f0b94e
  // an nsSHistory, but not much we can do with that).  So if we start using
Packit f0b94e
  // it here, we need to be careful to get to the docshell correctly.
Packit f0b94e
Packit f0b94e
  // For now just report what the Gecko-Content-Viewers category has
Packit f0b94e
  // to say for itself.
Packit f0b94e
  *aIsTypeSupported = nsIWebNavigationInfo::UNSUPPORTED;
Packit f0b94e
Packit f0b94e
  // We want to claim that the type for PDF documents is unsupported,
Packit f0b94e
  // so that the internal PDF viewer's stream converted will get used.
Packit f0b94e
  if (aType.LowerCaseEqualsLiteral("application/pdf") &&
Packit f0b94e
      nsContentUtils::IsPDFJSEnabled()) {
Packit f0b94e
    return NS_OK;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  const nsCString& flatType = PromiseFlatCString(aType);
Packit f0b94e
  nsresult rv = IsTypeSupportedInternal(flatType, aIsTypeSupported);
Packit f0b94e
  NS_ENSURE_SUCCESS(rv, rv);
Packit f0b94e
Packit f0b94e
  if (*aIsTypeSupported) {
Packit f0b94e
    return rv;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // As of FF 52, we only support flash and test plugins, so if the mime types
Packit f0b94e
  // don't match for that, exit before we start loading plugins.
Packit f0b94e
  if (!nsPluginHost::CanUsePluginForMIMEType(aType)) {
Packit f0b94e
    return NS_OK;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // If this request is for a docShell that isn't going to allow plugins,
Packit f0b94e
  // there's no need to try and find a plugin to handle it.
Packit f0b94e
  nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aWebNav));
Packit f0b94e
  bool allowed;
Packit f0b94e
  if (docShell && NS_SUCCEEDED(docShell->GetAllowPlugins(&allowed)) &&
Packit f0b94e
      !allowed) {
Packit f0b94e
    return NS_OK;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // Try reloading plugins in case they've changed.
Packit f0b94e
  nsCOMPtr<nsIPluginHost> pluginHost =
Packit f0b94e
      do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
Packit f0b94e
  if (pluginHost) {
Packit f0b94e
    // false will ensure that currently running plugins will not
Packit f0b94e
    // be shut down
Packit f0b94e
    rv = pluginHost->ReloadPlugins();
Packit f0b94e
    if (NS_SUCCEEDED(rv)) {
Packit f0b94e
      // OK, we reloaded plugins and there were new ones
Packit f0b94e
      // (otherwise NS_ERROR_PLUGINS_PLUGINSNOTCHANGED would have
Packit f0b94e
      // been returned).  Try checking whether we can handle the
Packit f0b94e
      // content now.
Packit f0b94e
      return IsTypeSupportedInternal(flatType, aIsTypeSupported);
Packit f0b94e
    }
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  return NS_OK;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
nsresult nsWebNavigationInfo::IsTypeSupportedInternal(const nsCString& aType,
Packit f0b94e
                                                      uint32_t* aIsSupported) {
Packit f0b94e
  NS_PRECONDITION(aIsSupported, "Null out param?");
Packit f0b94e
Packit f0b94e
  nsContentUtils::ContentViewerType vtype = nsContentUtils::TYPE_UNSUPPORTED;
Packit f0b94e
Packit f0b94e
  nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
Packit f0b94e
      nsContentUtils::FindInternalContentViewer(aType, &vtype);
Packit f0b94e
Packit f0b94e
  switch (vtype) {
Packit f0b94e
    case nsContentUtils::TYPE_UNSUPPORTED:
Packit f0b94e
      *aIsSupported = nsIWebNavigationInfo::UNSUPPORTED;
Packit f0b94e
      break;
Packit f0b94e
Packit f0b94e
    case nsContentUtils::TYPE_PLUGIN:
Packit f0b94e
      *aIsSupported = nsIWebNavigationInfo::PLUGIN;
Packit f0b94e
      break;
Packit f0b94e
Packit f0b94e
    case nsContentUtils::TYPE_UNKNOWN:
Packit f0b94e
      *aIsSupported = nsIWebNavigationInfo::OTHER;
Packit f0b94e
      break;
Packit f0b94e
Packit f0b94e
    case nsContentUtils::TYPE_CONTENT:
Packit f0b94e
      // XXXbz we only need this because images register for the same
Packit f0b94e
      // contractid as documents, so we can't tell them apart based on
Packit f0b94e
      // contractid.
Packit f0b94e
      if (imgLoader::SupportImageWithMimeType(aType.get())) {
Packit f0b94e
        *aIsSupported = nsIWebNavigationInfo::IMAGE;
Packit f0b94e
      } else {
Packit f0b94e
        *aIsSupported = nsIWebNavigationInfo::OTHER;
Packit f0b94e
      }
Packit f0b94e
      break;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  return NS_OK;
Packit f0b94e
}