1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "nsWebNavigationInfo.h"
8 
9 #include "mozilla/dom/BrowsingContext.h"
10 #include "nsIWebNavigation.h"
11 #include "nsServiceManagerUtils.h"
12 #include "nsIDocumentLoaderFactory.h"
13 #include "nsIDocShell.h"
14 #include "nsContentUtils.h"
15 #include "imgLoader.h"
16 #include "nsPluginHost.h"
17 
NS_IMPL_ISUPPORTS(nsWebNavigationInfo,nsIWebNavigationInfo)18 NS_IMPL_ISUPPORTS(nsWebNavigationInfo, nsIWebNavigationInfo)
19 
20 NS_IMETHODIMP
21 nsWebNavigationInfo::IsTypeSupported(const nsACString& aType,
22                                      nsIWebNavigation* aWebNav,
23                                      uint32_t* aIsTypeSupported) {
24   MOZ_ASSERT(aIsTypeSupported, "null out param?");
25 
26   *aIsTypeSupported = IsTypeSupported(aType, aWebNav);
27   return NS_OK;
28 }
29 
IsTypeSupported(const nsACString & aType,nsIWebNavigation * aWebNav)30 uint32_t nsWebNavigationInfo::IsTypeSupported(const nsACString& aType,
31                                               nsIWebNavigation* aWebNav) {
32   // Note to self: aWebNav could be an nsWebBrowser or an nsDocShell here (or
33   // an nsSHistory, but not much we can do with that).  So if we start using
34   // it here, we need to be careful to get to the docshell correctly.
35   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aWebNav));
36   auto* browsingContext = docShell ? docShell->GetBrowsingContext() : nullptr;
37   bool pluginsAllowed =
38       browsingContext ? browsingContext->GetAllowPlugins() : true;
39 
40   return IsTypeSupported(aType, pluginsAllowed);
41 }
42 
IsTypeSupported(const nsACString & aType,bool aPluginsAllowed)43 uint32_t nsWebNavigationInfo::IsTypeSupported(const nsACString& aType,
44                                               bool aPluginsAllowed) {
45   // We want to claim that the type for PDF documents is unsupported,
46   // so that the internal PDF viewer's stream converted will get used.
47   if (aType.LowerCaseEqualsLiteral("application/pdf") &&
48       nsContentUtils::IsPDFJSEnabled()) {
49     return nsIWebNavigationInfo::UNSUPPORTED;
50     ;
51   }
52 
53   const nsCString& flatType = PromiseFlatCString(aType);
54   return IsTypeSupportedInternal(flatType);
55 }
56 
IsTypeSupportedInternal(const nsCString & aType)57 uint32_t nsWebNavigationInfo::IsTypeSupportedInternal(const nsCString& aType) {
58   nsContentUtils::ContentViewerType vtype = nsContentUtils::TYPE_UNSUPPORTED;
59 
60   nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
61       nsContentUtils::FindInternalContentViewer(aType, &vtype);
62 
63   switch (vtype) {
64     case nsContentUtils::TYPE_UNSUPPORTED:
65       return nsIWebNavigationInfo::UNSUPPORTED;
66 
67     case nsContentUtils::TYPE_FALLBACK:
68       return nsIWebNavigationInfo::FALLBACK;
69 
70     case nsContentUtils::TYPE_UNKNOWN:
71       return nsIWebNavigationInfo::OTHER;
72 
73     case nsContentUtils::TYPE_CONTENT:
74       // XXXbz we only need this because images register for the same
75       // contractid as documents, so we can't tell them apart based on
76       // contractid.
77       if (imgLoader::SupportImageWithMimeType(aType)) {
78         return nsIWebNavigationInfo::IMAGE;
79       }
80       return nsIWebNavigationInfo::OTHER;
81   }
82 
83   return nsIWebNavigationInfo::UNSUPPORTED;
84 }
85