summaryrefslogtreecommitdiffstats
path: root/docshell/base/nsWebNavigationInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'docshell/base/nsWebNavigationInfo.cpp')
-rw-r--r--docshell/base/nsWebNavigationInfo.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/docshell/base/nsWebNavigationInfo.cpp b/docshell/base/nsWebNavigationInfo.cpp
new file mode 100644
index 0000000000..23c4ffaf16
--- /dev/null
+++ b/docshell/base/nsWebNavigationInfo.cpp
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsWebNavigationInfo.h"
+
+#include "mozilla/dom/BrowsingContext.h"
+#include "nsIWebNavigation.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIDocumentLoaderFactory.h"
+#include "nsIPluginHost.h"
+#include "nsIDocShell.h"
+#include "nsContentUtils.h"
+#include "imgLoader.h"
+#include "nsPluginHost.h"
+
+NS_IMPL_ISUPPORTS(nsWebNavigationInfo, nsIWebNavigationInfo)
+
+NS_IMETHODIMP
+nsWebNavigationInfo::IsTypeSupported(const nsACString& aType,
+ nsIWebNavigation* aWebNav,
+ uint32_t* aIsTypeSupported) {
+ MOZ_ASSERT(aIsTypeSupported, "null out param?");
+
+ *aIsTypeSupported = IsTypeSupported(aType, aWebNav);
+ return NS_OK;
+}
+
+uint32_t nsWebNavigationInfo::IsTypeSupported(const nsACString& aType,
+ nsIWebNavigation* aWebNav) {
+ // Note to self: aWebNav could be an nsWebBrowser or an nsDocShell here (or
+ // an nsSHistory, but not much we can do with that). So if we start using
+ // it here, we need to be careful to get to the docshell correctly.
+ nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aWebNav));
+ auto* browsingContext = docShell ? docShell->GetBrowsingContext() : nullptr;
+ bool pluginsAllowed =
+ browsingContext ? browsingContext->GetAllowPlugins() : true;
+
+ return IsTypeSupported(aType, pluginsAllowed);
+}
+
+uint32_t nsWebNavigationInfo::IsTypeSupported(const nsACString& aType,
+ bool aPluginsAllowed) {
+ // We want to claim that the type for PDF documents is unsupported,
+ // so that the internal PDF viewer's stream converted will get used.
+ if (aType.LowerCaseEqualsLiteral("application/pdf") &&
+ nsContentUtils::IsPDFJSEnabled()) {
+ return nsIWebNavigationInfo::UNSUPPORTED;
+ ;
+ }
+
+ const nsCString& flatType = PromiseFlatCString(aType);
+ uint32_t result = IsTypeSupportedInternal(flatType);
+ if (result != nsIWebNavigationInfo::UNSUPPORTED) {
+ return result;
+ }
+
+ // As of FF 52, we only support flash and test plugins, so if the mime types
+ // don't match for that, exit before we start loading plugins.
+ if (!nsPluginHost::CanUsePluginForMIMEType(aType)) {
+ return nsIWebNavigationInfo::UNSUPPORTED;
+ }
+
+ // If this request is for a docShell that isn't going to allow plugins,
+ // there's no need to try and find a plugin to handle it.
+ if (!aPluginsAllowed) {
+ return nsIWebNavigationInfo::UNSUPPORTED;
+ }
+
+ // Try reloading plugins in case they've changed.
+ nsCOMPtr<nsIPluginHost> pluginHost =
+ do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
+ if (pluginHost) {
+ // false will ensure that currently running plugins will not
+ // be shut down
+ nsresult rv = pluginHost->ReloadPlugins();
+ if (NS_SUCCEEDED(rv)) {
+ // OK, we reloaded plugins and there were new ones
+ // (otherwise NS_ERROR_PLUGINS_PLUGINSNOTCHANGED would have
+ // been returned). Try checking whether we can handle the
+ // content now.
+ return IsTypeSupportedInternal(flatType);
+ }
+ }
+
+ return nsIWebNavigationInfo::UNSUPPORTED;
+}
+
+uint32_t nsWebNavigationInfo::IsTypeSupportedInternal(const nsCString& aType) {
+ nsContentUtils::ContentViewerType vtype = nsContentUtils::TYPE_UNSUPPORTED;
+
+ nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
+ nsContentUtils::FindInternalContentViewer(aType, &vtype);
+
+ switch (vtype) {
+ case nsContentUtils::TYPE_UNSUPPORTED:
+ return nsIWebNavigationInfo::UNSUPPORTED;
+
+ case nsContentUtils::TYPE_PLUGIN:
+ return nsIWebNavigationInfo::PLUGIN;
+
+ case nsContentUtils::TYPE_UNKNOWN:
+ return nsIWebNavigationInfo::OTHER;
+
+ case nsContentUtils::TYPE_CONTENT:
+ // XXXbz we only need this because images register for the same
+ // contractid as documents, so we can't tell them apart based on
+ // contractid.
+ if (imgLoader::SupportImageWithMimeType(aType.get())) {
+ return nsIWebNavigationInfo::IMAGE;
+ } else {
+ return nsIWebNavigationInfo::OTHER;
+ }
+ }
+
+ return nsIWebNavigationInfo::UNSUPPORTED;
+}