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