From b4c7d284fbc494e0aad663c4ebfe4cd51d9a9148 Mon Sep 17 00:00:00 2001 From: Mounir Lamouri Date: Wed, 2 Nov 2011 14:44:16 +0100 Subject: [PATCH] Bug 695287 - Move Navigator declaration and definition outside of nsGlobalWindow.{h,cpp}. r=Ms2ger This patch is creating Navigator.h and Navigator.cpp and makes Navigator part of the mozilla::dom namespace. --- dom/base/Makefile.in | 1 + dom/base/Navigator.cpp | 852 +++++++++++++++++++++++++++++++ dom/base/Navigator.h | 113 ++++ dom/base/nsDOMClassInfo.cpp | 9 +- dom/base/nsGlobalWindow.cpp | 778 +--------------------------- dom/base/nsGlobalWindow.h | 64 +-- dom/base/nsPluginArray.cpp | 7 +- dom/base/nsPluginArray.h | 13 +- dom/workers/RuntimeService.cpp | 2 +- layout/build/nsLayoutStatics.cpp | 2 + 10 files changed, 1004 insertions(+), 837 deletions(-) create mode 100644 dom/base/Navigator.cpp create mode 100644 dom/base/Navigator.h diff --git a/dom/base/Makefile.in b/dom/base/Makefile.in index 597120833012..a4d715ff0268 100644 --- a/dom/base/Makefile.in +++ b/dom/base/Makefile.in @@ -122,6 +122,7 @@ CPPSRCS = \ nsDOMNavigationTiming.cpp \ nsPerformance.cpp \ nsDOMMemoryReporter.cpp \ + Navigator.cpp \ $(NULL) include $(topsrcdir)/dom/dom-config.mk diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp new file mode 100644 index 000000000000..68590e4cef0e --- /dev/null +++ b/dom/base/Navigator.cpp @@ -0,0 +1,852 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=2 et tw=78: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Travis Bogard + * Brendan Eich + * David Hyatt (hyatt@netscape.com) + * Dan Rosen + * Vidur Apparao + * Johnny Stenback + * Mark Hammond + * Ryan Jones + * Jeff Walden + * Ben Bucksch + * Emanuele Costa + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Needs to be first. +#include "base/basictypes.h" + +#include "Navigator.h" +#include "nsIXULAppInfo.h" +#include "nsPluginArray.h" +#include "nsMimeTypeArray.h" +#include "nsDesktopNotification.h" +#include "nsGeolocation.h" +#include "nsIHttpProtocolHandler.h" +#include "nsICachingChannel.h" +#include "nsIDocShell.h" +#include "nsIWebContentHandlerRegistrar.h" +#include "nsICookiePermission.h" +#include "nsIScriptSecurityManager.h" +#include "nsIJSContextStack.h" +#include "nsCharSeparatedTokenizer.h" +#include "nsContentUtils.h" +#include "nsUnicharUtils.h" +#include "mozilla/Preferences.h" +#include "mozilla/Telemetry.h" + +// This should not be in the namespace. +DOMCI_DATA(Navigator, mozilla::dom::Navigator) + +namespace mozilla { +namespace dom { + +static const char sJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1"; +bool Navigator::sDoNotTrackEnabled = false; + +/* static */ +void +Navigator::Init() +{ + Preferences::AddBoolVarCache(&sDoNotTrackEnabled, + "privacy.donottrackheader.enabled", + false); +} + +Navigator::Navigator(nsIDocShell* aDocShell) + : mDocShell(aDocShell) +{ +} + +Navigator::~Navigator() +{ + if (mMimeTypes) { + mMimeTypes->Invalidate(); + } + + if (mPlugins) { + mPlugins->Invalidate(); + } +} + +NS_INTERFACE_MAP_BEGIN(Navigator) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator) + NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator) + NS_INTERFACE_MAP_ENTRY(nsIDOMClientInformation) + NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorGeolocation) + NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorDesktopNotification) + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator) +NS_INTERFACE_MAP_END + +NS_IMPL_ADDREF(Navigator) +NS_IMPL_RELEASE(Navigator) + +void +Navigator::SetDocShell(nsIDocShell* aDocShell) +{ + mDocShell = aDocShell; + + if (mPlugins) { + mPlugins->SetDocShell(aDocShell); + } + + // If there is a page transition, make sure delete the geolocation object. + if (mGeolocation) { + mGeolocation->Shutdown(); + mGeolocation = nsnull; + } + + if (mNotification) { + mNotification->Shutdown(); + mNotification = nsnull; + } +} + +//***************************************************************************** +// Navigator::nsIDOMNavigator +//***************************************************************************** + +NS_IMETHODIMP +Navigator::GetUserAgent(nsAString& aUserAgent) +{ + return NS_GetNavigatorUserAgent(aUserAgent); +} + +NS_IMETHODIMP +Navigator::GetAppCodeName(nsAString& aAppCodeName) +{ + nsresult rv; + + nsCOMPtr + service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCAutoString appName; + rv = service->GetAppName(appName); + CopyASCIItoUTF16(appName, aAppCodeName); + + return rv; +} + +NS_IMETHODIMP +Navigator::GetAppVersion(nsAString& aAppVersion) +{ + return NS_GetNavigatorAppVersion(aAppVersion); +} + +NS_IMETHODIMP +Navigator::GetAppName(nsAString& aAppName) +{ + return NS_GetNavigatorAppName(aAppName); +} + +/** + * JS property navigator.language, exposed to web content. + * Take first value from Accept-Languages (HTTP header), which is + * the "content language" freely set by the user in the Pref window. + * + * Do not use UI language (chosen app locale) here. + * See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers" + * + * "en", "en-US" and "i-cherokee" and "" are valid. + * Fallback in case of invalid pref should be "" (empty string), to + * let site do fallback, e.g. to site's local language. + */ +NS_IMETHODIMP +Navigator::GetLanguage(nsAString& aLanguage) +{ + // E.g. "de-de, en-us,en". + const nsAdoptingString& acceptLang = + Preferences::GetLocalizedString("intl.accept_languages"); + + // Take everything before the first "," or ";", without trailing space. + nsCharSeparatedTokenizer langTokenizer(acceptLang, ','); + const nsSubstring &firstLangPart = langTokenizer.nextToken(); + nsCharSeparatedTokenizer qTokenizer(firstLangPart, ';'); + aLanguage.Assign(qTokenizer.nextToken()); + + // Checks and fixups: + // replace "_" with "-" to avoid POSIX/Windows "en_US" notation. + if (aLanguage.Length() > 2 && aLanguage[2] == PRUnichar('_')) { + aLanguage.Replace(2, 1, PRUnichar('-')); // TODO replace all + } + + // Use uppercase for country part, e.g. "en-US", not "en-us", see BCP47 + // only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe". + if (aLanguage.Length() <= 2) { + return NS_OK; + } + + nsCharSeparatedTokenizer localeTokenizer(aLanguage, '-'); + PRInt32 pos = 0; + bool first = true; + while (localeTokenizer.hasMoreTokens()) { + const nsSubstring& code = localeTokenizer.nextToken(); + + if (code.Length() == 2 && !first) { + nsAutoString upper(code); + ToUpperCase(upper); + aLanguage.Replace(pos, code.Length(), upper); + } + + pos += code.Length() + 1; // 1 is the separator + first = false; + } + + return NS_OK; +} + +NS_IMETHODIMP +Navigator::GetPlatform(nsAString& aPlatform) +{ + return NS_GetNavigatorPlatform(aPlatform); +} + +NS_IMETHODIMP +Navigator::GetOscpu(nsAString& aOSCPU) +{ + if (!nsContentUtils::IsCallerTrustedForRead()) { + const nsAdoptingString& override = + Preferences::GetString("general.oscpu.override"); + + if (override) { + aOSCPU = override; + return NS_OK; + } + } + + nsresult rv; + + nsCOMPtr + service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCAutoString oscpu; + rv = service->GetOscpu(oscpu); + CopyASCIItoUTF16(oscpu, aOSCPU); + + return rv; +} + +NS_IMETHODIMP +Navigator::GetVendor(nsAString& aVendor) +{ + aVendor.Truncate(); + return NS_OK; +} + +NS_IMETHODIMP +Navigator::GetVendorSub(nsAString& aVendorSub) +{ + aVendorSub.Truncate(); + return NS_OK; +} + +NS_IMETHODIMP +Navigator::GetProduct(nsAString& aProduct) +{ + nsresult rv; + + nsCOMPtr + service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCAutoString product; + rv = service->GetProduct(product); + CopyASCIItoUTF16(product, aProduct); + + return rv; +} + +NS_IMETHODIMP +Navigator::GetProductSub(nsAString& aProductSub) +{ + if (!nsContentUtils::IsCallerTrustedForRead()) { + const nsAdoptingString& override = + Preferences::GetString("general.productSub.override"); + + if (override) { + aProductSub = override; + return NS_OK; + } + + // 'general.useragent.productSub' backwards compatible with 1.8 branch. + const nsAdoptingString& override2 = + Preferences::GetString("general.useragent.productSub"); + + if (override2) { + aProductSub = override2; + return NS_OK; + } + } + + nsresult rv; + + nsCOMPtr + service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCAutoString productSub; + rv = service->GetProductSub(productSub); + CopyASCIItoUTF16(productSub, aProductSub); + + return rv; +} + +NS_IMETHODIMP +Navigator::GetMimeTypes(nsIDOMMimeTypeArray** aMimeTypes) +{ + if (!mMimeTypes) { + mMimeTypes = new nsMimeTypeArray(this); + } + + NS_ADDREF(*aMimeTypes = mMimeTypes); + + return NS_OK; +} + +NS_IMETHODIMP +Navigator::GetPlugins(nsIDOMPluginArray** aPlugins) +{ + if (!mPlugins) { + mPlugins = new nsPluginArray(this, mDocShell); + } + + NS_ADDREF(*aPlugins = mPlugins); + + return NS_OK; +} + +// Values for the network.cookie.cookieBehavior pref are documented in +// nsCookieService.cpp. +#define COOKIE_BEHAVIOR_REJECT 2 + +NS_IMETHODIMP +Navigator::GetCookieEnabled(bool* aCookieEnabled) +{ + *aCookieEnabled = + (Preferences::GetInt("network.cookie.cookieBehavior", + COOKIE_BEHAVIOR_REJECT) != COOKIE_BEHAVIOR_REJECT); + + // Check whether an exception overrides the global cookie behavior + // Note that the code for getting the URI here matches that in + // nsHTMLDocument::SetCookie. + nsCOMPtr doc = do_GetInterface(mDocShell); + if (!doc) { + return NS_OK; + } + + nsCOMPtr codebaseURI; + doc->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI)); + + if (!codebaseURI) { + // Not a codebase, so technically can't set cookies, but let's + // just return the default value. + return NS_OK; + } + + nsCOMPtr permMgr = + do_GetService(NS_COOKIEPERMISSION_CONTRACTID); + NS_ENSURE_TRUE(permMgr, NS_OK); + + // Pass null for the channel, just like the cookie service does. + nsCookieAccess access; + nsresult rv = permMgr->CanAccess(codebaseURI, nsnull, &access); + NS_ENSURE_SUCCESS(rv, NS_OK); + + if (access != nsICookiePermission::ACCESS_DEFAULT) { + *aCookieEnabled = access != nsICookiePermission::ACCESS_DENY; + } + + return NS_OK; +} + +NS_IMETHODIMP +Navigator::GetOnLine(bool* aOnline) +{ + NS_PRECONDITION(aOnline, "Null out param"); + + *aOnline = !NS_IsOffline(); + return NS_OK; +} + +NS_IMETHODIMP +Navigator::GetBuildID(nsAString& aBuildID) +{ + if (!nsContentUtils::IsCallerTrustedForRead()) { + const nsAdoptingString& override = + Preferences::GetString("general.buildID.override"); + + if (override) { + aBuildID = override; + return NS_OK; + } + } + + nsCOMPtr appInfo = + do_GetService("@mozilla.org/xre/app-info;1"); + if (!appInfo) { + return NS_ERROR_NOT_IMPLEMENTED; + } + + nsCAutoString buildID; + nsresult rv = appInfo->GetAppBuildID(buildID); + if (NS_FAILED(rv)) { + return rv; + } + + aBuildID.Truncate(); + AppendASCIItoUTF16(buildID, aBuildID); + return NS_OK; +} + +NS_IMETHODIMP +Navigator::GetDoNotTrack(nsAString &aResult) +{ + if (sDoNotTrackEnabled) { + aResult.AssignLiteral("yes"); + } else { + aResult.AssignLiteral("unspecified"); + } + + return NS_OK; +} + +NS_IMETHODIMP +Navigator::JavaEnabled(bool* aReturn) +{ + Telemetry::AutoTimer telemetryTimer; + // Return true if we have a handler for "application/x-java-vm", + // otherwise return false. + *aReturn = false; + + if (!mMimeTypes) { + mMimeTypes = new nsMimeTypeArray(this); + } + + RefreshMIMEArray(); + + PRUint32 count; + mMimeTypes->GetLength(&count); + for (PRUint32 i = 0; i < count; i++) { + nsresult rv; + nsIDOMMimeType* type = mMimeTypes->GetItemAt(i, &rv); + nsAutoString mimeString; + if (type && NS_SUCCEEDED(type->GetType(mimeString))) { + if (mimeString.EqualsLiteral("application/x-java-vm")) { + *aReturn = true; + break; + } + } + } + + return NS_OK; +} + +void +Navigator::LoadingNewDocument() +{ + // Release these so that they will be recreated for the + // new document (if requested). The plugins or mime types + // arrays may have changed. See bug 150087. + if (mMimeTypes) { + mMimeTypes->Invalidate(); + mMimeTypes = nsnull; + } + + if (mPlugins) { + mPlugins->Invalidate(); + mPlugins = nsnull; + } + + if (mGeolocation) { + mGeolocation->Shutdown(); + mGeolocation = nsnull; + } + + if (mNotification) { + mNotification->Shutdown(); + mNotification = nsnull; + } + +} + +nsresult +Navigator::RefreshMIMEArray() +{ + if (mMimeTypes) { + return mMimeTypes->Refresh(); + } + + return NS_OK; +} + +bool +Navigator::HasDesktopNotificationSupport() +{ + return Preferences::GetBool("notification.feature.enabled", false); +} + +//***************************************************************************** +// Navigator::nsIDOMClientInformation +//***************************************************************************** + +NS_IMETHODIMP +Navigator::RegisterContentHandler(const nsAString& aMIMEType, + const nsAString& aURI, + const nsAString& aTitle) +{ + if (!mDocShell) { + return NS_OK; + } + + nsCOMPtr registrar = + do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID); + if (!registrar) { + return NS_OK; + } + + nsCOMPtr contentDOMWindow = do_GetInterface(mDocShell); + if (!contentDOMWindow) { + return NS_OK; + } + + return registrar->RegisterContentHandler(aMIMEType, aURI, aTitle, + contentDOMWindow); +} + +NS_IMETHODIMP +Navigator::RegisterProtocolHandler(const nsAString& aProtocol, + const nsAString& aURI, + const nsAString& aTitle) +{ + if (!mDocShell) { + return NS_OK; + } + + nsCOMPtr registrar = + do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID); + if (!registrar) { + return NS_OK; + } + + nsCOMPtr contentDOMWindow = do_GetInterface(mDocShell); + if (!contentDOMWindow) { + return NS_OK; + } + + return registrar->RegisterProtocolHandler(aProtocol, aURI, aTitle, + contentDOMWindow); +} + +NS_IMETHODIMP +Navigator::MozIsLocallyAvailable(const nsAString &aURI, + bool aWhenOffline, + bool* aIsAvailable) +{ + nsCOMPtr uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI); + NS_ENSURE_SUCCESS(rv, rv); + + // This method of checking the cache will only work for http/https urls. + bool match; + rv = uri->SchemeIs("http", &match); + NS_ENSURE_SUCCESS(rv, rv); + + if (!match) { + rv = uri->SchemeIs("https", &match); + NS_ENSURE_SUCCESS(rv, rv); + if (!match) { + return NS_ERROR_DOM_BAD_URI; + } + } + + // Same origin check. + nsCOMPtr stack = do_GetService(sJSStackContractID); + NS_ENSURE_TRUE(stack, NS_ERROR_FAILURE); + + JSContext* cx = nsnull; + rv = stack->Peek(&cx); + NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE); + + rv = nsContentUtils::GetSecurityManager()->CheckSameOrigin(cx, uri); + NS_ENSURE_SUCCESS(rv, rv); + + // These load flags cause an error to be thrown if there is no + // valid cache entry, and skip the load if there is. + // If the cache is busy, assume that it is not yet available rather + // than waiting for it to become available. + PRUint32 loadFlags = nsIChannel::INHIBIT_CACHING | + nsICachingChannel::LOAD_NO_NETWORK_IO | + nsICachingChannel::LOAD_ONLY_IF_MODIFIED | + nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY; + + if (aWhenOffline) { + loadFlags |= nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE | + nsICachingChannel::LOAD_ONLY_FROM_CACHE | + nsIRequest::LOAD_FROM_CACHE; + } + + nsCOMPtr channel; + rv = NS_NewChannel(getter_AddRefs(channel), uri, + nsnull, nsnull, nsnull, loadFlags); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr stream; + rv = channel->Open(getter_AddRefs(stream)); + NS_ENSURE_SUCCESS(rv, rv); + + stream->Close(); + + nsresult status; + rv = channel->GetStatus(&status); + NS_ENSURE_SUCCESS(rv, rv); + + if (NS_FAILED(status)) { + *aIsAvailable = false; + return NS_OK; + } + + nsCOMPtr httpChannel = do_QueryInterface(channel); + return httpChannel->GetRequestSucceeded(aIsAvailable); +} + +//***************************************************************************** +// Navigator::nsIDOMNavigatorGeolocation +//***************************************************************************** + +NS_IMETHODIMP Navigator::GetGeolocation(nsIDOMGeoGeolocation** _retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + *_retval = nsnull; + + if (!Preferences::GetBool("geo.enabled", true)) { + return NS_OK; + } + + if (mGeolocation) { + NS_ADDREF(*_retval = mGeolocation); + return NS_OK; + } + + if (!mDocShell) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr contentDOMWindow = do_GetInterface(mDocShell); + if (!contentDOMWindow) { + return NS_ERROR_FAILURE; + } + + mGeolocation = new nsGeolocation(); + if (!mGeolocation) { + return NS_ERROR_FAILURE; + } + + if (NS_FAILED(mGeolocation->Init(contentDOMWindow))) { + mGeolocation = nsnull; + return NS_ERROR_FAILURE; + } + + NS_ADDREF(*_retval = mGeolocation); + return NS_OK; +} + +//***************************************************************************** +// Navigator::nsIDOMNavigatorDesktopNotification +//***************************************************************************** + +NS_IMETHODIMP Navigator::GetMozNotification(nsIDOMDesktopNotificationCenter** aRetVal) +{ + NS_ENSURE_ARG_POINTER(aRetVal); + *aRetVal = nsnull; + + if (mNotification) { + NS_ADDREF(*aRetVal = mNotification); + return NS_OK; + } + + nsCOMPtr window = do_GetInterface(mDocShell); + NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); + + nsCOMPtr document = do_GetInterface(mDocShell); + NS_ENSURE_TRUE(document, NS_ERROR_FAILURE); + + nsIScriptGlobalObject* sgo = document->GetScopeObject(); + NS_ENSURE_TRUE(sgo, NS_ERROR_FAILURE); + + nsIScriptContext* scx = sgo->GetContext(); + NS_ENSURE_TRUE(scx, NS_ERROR_FAILURE); + + mNotification = new nsDesktopNotificationCenter(window->GetCurrentInnerWindow(), + scx); + + NS_ADDREF(*aRetVal = mNotification); + return NS_OK; +} + +PRInt64 +Navigator::SizeOf() const +{ + PRInt64 size = sizeof(*this); + + // TODO: add SizeOf() to nsMimeTypeArray, bug 674113. + size += mMimeTypes ? sizeof(*mMimeTypes.get()) : 0; + // TODO: add SizeOf() to nsPluginArray, bug 674114. + size += mPlugins ? sizeof(*mPlugins.get()) : 0; + // TODO: add SizeOf() to nsGeolocation, bug 674115. + size += mGeolocation ? sizeof(*mGeolocation.get()) : 0; + // TODO: add SizeOf() to nsDesktopNotificationCenter, bug 674116. + size += mNotification ? sizeof(*mNotification.get()) : 0; + + return size; +} + +} // namespace dom +} // namespace mozilla + +nsresult +NS_GetNavigatorUserAgent(nsAString& aUserAgent) +{ + nsresult rv; + + nsCOMPtr + service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCAutoString ua; + rv = service->GetUserAgent(ua); + CopyASCIItoUTF16(ua, aUserAgent); + + return rv; +} + +nsresult +NS_GetNavigatorPlatform(nsAString& aPlatform) +{ + if (!nsContentUtils::IsCallerTrustedForRead()) { + const nsAdoptingString& override = + mozilla::Preferences::GetString("general.platform.override"); + + if (override) { + aPlatform = override; + return NS_OK; + } + } + + nsresult rv; + + nsCOMPtr + service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + // Sorry for the #if platform ugliness, but Communicator is likewise + // hardcoded and we are seeking backward compatibility here (bug 47080). +#if defined(_WIN64) + aPlatform.AssignLiteral("Win64"); +#elif defined(WIN32) + aPlatform.AssignLiteral("Win32"); +#elif defined(XP_MACOSX) && defined(__ppc__) + aPlatform.AssignLiteral("MacPPC"); +#elif defined(XP_MACOSX) && defined(__i386__) + aPlatform.AssignLiteral("MacIntel"); +#elif defined(XP_MACOSX) && defined(__x86_64__) + aPlatform.AssignLiteral("MacIntel"); +#elif defined(XP_OS2) + aPlatform.AssignLiteral("OS/2"); +#else + // XXX Communicator uses compiled-in build-time string defines + // to indicate the platform it was compiled *for*, not what it is + // currently running *on* which is what this does. + nsCAutoString plat; + rv = service->GetOscpu(plat); + CopyASCIItoUTF16(plat, aPlatform); +#endif + + return rv; +} +nsresult +NS_GetNavigatorAppVersion(nsAString& aAppVersion) +{ + if (!nsContentUtils::IsCallerTrustedForRead()) { + const nsAdoptingString& override = + mozilla::Preferences::GetString("general.appversion.override"); + + if (override) { + aAppVersion = override; + return NS_OK; + } + } + + nsresult rv; + + nsCOMPtr + service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCAutoString str; + rv = service->GetAppVersion(str); + CopyASCIItoUTF16(str, aAppVersion); + NS_ENSURE_SUCCESS(rv, rv); + + aAppVersion.AppendLiteral(" ("); + + rv = service->GetPlatform(str); + NS_ENSURE_SUCCESS(rv, rv); + + AppendASCIItoUTF16(str, aAppVersion); + aAppVersion.Append(PRUnichar(')')); + + return rv; +} + +nsresult +NS_GetNavigatorAppName(nsAString& aAppName) +{ + if (!nsContentUtils::IsCallerTrustedForRead()) { + const nsAdoptingString& override = + mozilla::Preferences::GetString("general.appname.override"); + + if (override) { + aAppName = override; + return NS_OK; + } + } + + aAppName.AssignLiteral("Netscape"); + return NS_OK; +} diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h new file mode 100644 index 000000000000..048bccccb764 --- /dev/null +++ b/dom/base/Navigator.h @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 et tw=80: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Travis Bogard + * Dan Rosen + * Vidur Apparao + * Johnny Stenback + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef mozilla_dom_Navigator_h +#define mozilla_dom_Navigator_h + +#include "nsIDOMNavigator.h" +#include "nsIDOMNavigatorGeolocation.h" +#include "nsIDOMNavigatorDesktopNotification.h" +#include "nsIDOMClientInformation.h" +#include "nsAutoPtr.h" + +class nsPluginArray; +class nsMimeTypeArray; +class nsGeolocation; +class nsDesktopNotificationCenter; +class nsIDocShell; + +//***************************************************************************** +// Navigator: Script "navigator" object +//***************************************************************************** + +namespace mozilla { +namespace dom { + +class Navigator : public nsIDOMNavigator, + public nsIDOMClientInformation, + public nsIDOMNavigatorGeolocation, + public nsIDOMNavigatorDesktopNotification +{ +public: + Navigator(nsIDocShell *aDocShell); + virtual ~Navigator(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIDOMNAVIGATOR + NS_DECL_NSIDOMCLIENTINFORMATION + NS_DECL_NSIDOMNAVIGATORGEOLOCATION + NS_DECL_NSIDOMNAVIGATORDESKTOPNOTIFICATION + + static void Init(); + + void SetDocShell(nsIDocShell *aDocShell); + nsIDocShell *GetDocShell() + { + return mDocShell; + } + + void LoadingNewDocument(); + nsresult RefreshMIMEArray(); + + static bool HasDesktopNotificationSupport(); + + PRInt64 SizeOf() const; + +private: + static bool sDoNotTrackEnabled; + + nsRefPtr mMimeTypes; + nsRefPtr mPlugins; + nsRefPtr mGeolocation; + nsRefPtr mNotification; + nsIDocShell* mDocShell; // weak reference +}; + +} // namespace dom +} // namespace mozilla + +nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent); +nsresult NS_GetNavigatorPlatform(nsAString& aPlatform); +nsresult NS_GetNavigatorAppVersion(nsAString& aAppVersion); +nsresult NS_GetNavigatorAppName(nsAString& aAppName); + +#endif // mozilla_dom_Navigator_h diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 2a79b8177bb0..f2b5ed18f4eb 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -470,6 +470,11 @@ #include "nsIDOMDesktopNotification.h" #include "nsIDOMNavigatorDesktopNotification.h" +#include "nsIDOMNavigatorGeolocation.h" +#include "Navigator.h" + +#include "nsPluginArray.h" +#include "nsMimeTypeArray.h" // Simple gestures include #include "nsIDOMSimpleGestureEvent.h" @@ -2278,7 +2283,7 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigator) DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorGeolocation) DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMNavigatorDesktopNotification, - nsNavigator::HasDesktopNotificationSupport()) + Navigator::HasDesktopNotificationSupport()) DOM_CLASSINFO_MAP_ENTRY(nsIDOMClientInformation) DOM_CLASSINFO_MAP_END @@ -7131,7 +7136,7 @@ nsNavigatorSH::PreCreate(nsISupports *nativeObj, JSContext *cx, return NS_OK; } - nsNavigator *nav = (nsNavigator *)safeNav.get(); + Navigator *nav = static_cast(safeNav.get()); nsIDocShell *ds = nav->GetDocShell(); if (!ds) { NS_WARNING("Refusing to create a navigator in the wrong scope"); diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 8f719e1edd6c..f62e6d8f29a3 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -54,6 +54,7 @@ // Local Includes #include "nsGlobalWindow.h" +#include "Navigator.h" #include "nsScreen.h" #include "nsHistory.h" #include "nsPerformance.h" @@ -277,7 +278,6 @@ static bool gDragServiceDisabled = false; static FILE *gDumpFile = nsnull; static PRUint64 gNextWindowID = 0; static PRUint32 gSerialCounter = 0; -static bool gDoNotTrackEnabled = false; #ifdef DEBUG_jst PRInt32 gTimeoutCnt = 0; @@ -962,10 +962,6 @@ nsGlobalWindow::Init() NS_ASSERTION(gEntropyCollector, "gEntropyCollector should have been initialized!"); - mozilla::Preferences::AddBoolVarCache(&gDoNotTrackEnabled, - "privacy.donottrackheader.enabled", - false); - #ifdef PR_LOGGING gDOMLeakPRLog = PR_NewLogModule("DOMLeak"); NS_ASSERTION(gDOMLeakPRLog, "gDOMLeakPRLog should have been initialized!"); @@ -1737,7 +1733,7 @@ public: WindowStateHolder(nsGlobalWindow *aWindow, nsIXPConnectJSObjectHolder *aHolder, - nsNavigator *aNavigator, + Navigator *aNavigator, nsIXPConnectJSObjectHolder *aOuterProto, nsIXPConnectJSObjectHolder *aOuterRealProto); @@ -1745,7 +1741,7 @@ public: nsIXPConnectJSObjectHolder *GetInnerWindowHolder() { return mInnerWindowHolder; } - nsNavigator* GetNavigator() { return mNavigator; } + Navigator* GetNavigator() { return mNavigator; } nsIXPConnectJSObjectHolder* GetOuterProto() { return mOuterProto; } nsIXPConnectJSObjectHolder* GetOuterRealProto() { return mOuterRealProto; } @@ -1766,7 +1762,7 @@ protected: // We hold onto this to make sure the inner window doesn't go away. The outer // window ends up recalculating it anyway. nsCOMPtr mInnerWindowHolder; - nsRefPtr mNavigator; + nsRefPtr mNavigator; nsCOMPtr mOuterProto; nsCOMPtr mOuterRealProto; }; @@ -1775,7 +1771,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(WindowStateHolder, WINDOWSTATEHOLDER_IID) WindowStateHolder::WindowStateHolder(nsGlobalWindow *aWindow, nsIXPConnectJSObjectHolder *aHolder, - nsNavigator *aNavigator, + Navigator *aNavigator, nsIXPConnectJSObjectHolder *aOuterProto, nsIXPConnectJSObjectHolder *aOuterRealProto) : mInnerWindow(aWindow), @@ -3009,10 +3005,7 @@ nsGlobalWindow::GetNavigator(nsIDOMNavigator** aNavigator) *aNavigator = nsnull; if (!mNavigator) { - mNavigator = new nsNavigator(mDocShell); - if (!mNavigator) { - return NS_ERROR_OUT_OF_MEMORY; - } + mNavigator = new Navigator(mDocShell); } NS_ADDREF(*aNavigator = mNavigator); @@ -10706,748 +10699,6 @@ NS_NewScriptGlobalObject(bool aIsChrome, bool aIsModalContentWindow, return NS_OK; } -//***************************************************************************** -//*** nsNavigator: Object Management -//***************************************************************************** - -nsNavigator::nsNavigator(nsIDocShell *aDocShell) - : mDocShell(aDocShell) -{ -} - -nsNavigator::~nsNavigator() -{ - if (mMimeTypes) - mMimeTypes->Invalidate(); - if (mPlugins) - mPlugins->Invalidate(); -} - -//***************************************************************************** -// nsNavigator::nsISupports -//***************************************************************************** - - -DOMCI_DATA(Navigator, nsNavigator) - -// QueryInterface implementation for nsNavigator -NS_INTERFACE_MAP_BEGIN(nsNavigator) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator) - NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator) - NS_INTERFACE_MAP_ENTRY(nsIDOMClientInformation) - NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorGeolocation) - NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorDesktopNotification) - NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator) -NS_INTERFACE_MAP_END - - -NS_IMPL_ADDREF(nsNavigator) -NS_IMPL_RELEASE(nsNavigator) - - -void -nsNavigator::SetDocShell(nsIDocShell *aDocShell) -{ - mDocShell = aDocShell; - if (mPlugins) - mPlugins->SetDocShell(aDocShell); - - // if there is a page transition, make sure delete the geolocation object - if (mGeolocation) - { - mGeolocation->Shutdown(); - mGeolocation = nsnull; - } - - if (mNotification) - { - mNotification->Shutdown(); - mNotification = nsnull; - } -} - -//***************************************************************************** -// nsNavigator::nsIDOMNavigator -//***************************************************************************** - -nsresult -NS_GetNavigatorUserAgent(nsAString& aUserAgent) -{ - nsresult rv; - nsCOMPtr - service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); - if (NS_SUCCEEDED(rv)) { - nsCAutoString ua; - rv = service->GetUserAgent(ua); - CopyASCIItoUTF16(ua, aUserAgent); - } - - return rv; -} - -nsresult -NS_GetNavigatorPlatform(nsAString& aPlatform) -{ - if (!nsContentUtils::IsCallerTrustedForRead()) { - const nsAdoptingString& override = - Preferences::GetString("general.platform.override"); - - if (override) { - aPlatform = override; - return NS_OK; - } - } - - nsresult rv; - nsCOMPtr - service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); - if (NS_SUCCEEDED(rv)) { - // sorry for the #if platform ugliness, but Communicator is - // likewise hardcoded and we're seeking backward compatibility - // here (bug 47080) -#if defined(_WIN64) - aPlatform.AssignLiteral("Win64"); -#elif defined(WIN32) - aPlatform.AssignLiteral("Win32"); -#elif defined(XP_MACOSX) && defined(__ppc__) - aPlatform.AssignLiteral("MacPPC"); -#elif defined(XP_MACOSX) && defined(__i386__) - aPlatform.AssignLiteral("MacIntel"); -#elif defined(XP_MACOSX) && defined(__x86_64__) - aPlatform.AssignLiteral("MacIntel"); -#elif defined(XP_OS2) - aPlatform.AssignLiteral("OS/2"); -#else - // XXX Communicator uses compiled-in build-time string defines - // to indicate the platform it was compiled *for*, not what it is - // currently running *on* which is what this does. - nsCAutoString plat; - rv = service->GetOscpu(plat); - CopyASCIItoUTF16(plat, aPlatform); -#endif - } - - return rv; -} -nsresult -NS_GetNavigatorAppVersion(nsAString& aAppVersion) -{ - if (!nsContentUtils::IsCallerTrustedForRead()) { - const nsAdoptingString& override = - Preferences::GetString("general.appversion.override"); - - if (override) { - aAppVersion = override; - return NS_OK; - } - } - - nsresult rv; - nsCOMPtr - service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); - if (NS_SUCCEEDED(rv)) { - nsCAutoString str; - rv = service->GetAppVersion(str); - CopyASCIItoUTF16(str, aAppVersion); - if (NS_FAILED(rv)) - return rv; - - aAppVersion.AppendLiteral(" ("); - - rv = service->GetPlatform(str); - if (NS_FAILED(rv)) - return rv; - - AppendASCIItoUTF16(str, aAppVersion); - - aAppVersion.Append(PRUnichar(')')); - } - - return rv; -} - -nsresult -NS_GetNavigatorAppName(nsAString& aAppName) -{ - if (!nsContentUtils::IsCallerTrustedForRead()) { - const nsAdoptingString& override = - Preferences::GetString("general.appname.override"); - - if (override) { - aAppName = override; - return NS_OK; - } - } - - aAppName.AssignLiteral("Netscape"); - return NS_OK; -} - -NS_IMETHODIMP -nsNavigator::GetUserAgent(nsAString& aUserAgent) -{ - return NS_GetNavigatorUserAgent(aUserAgent); -} - -NS_IMETHODIMP -nsNavigator::GetAppCodeName(nsAString& aAppCodeName) -{ - nsresult rv; - nsCOMPtr - service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); - if (NS_SUCCEEDED(rv)) { - nsCAutoString appName; - rv = service->GetAppName(appName); - CopyASCIItoUTF16(appName, aAppCodeName); - } - - return rv; -} - -NS_IMETHODIMP -nsNavigator::GetAppVersion(nsAString& aAppVersion) -{ - return NS_GetNavigatorAppVersion(aAppVersion); -} - -NS_IMETHODIMP -nsNavigator::GetAppName(nsAString& aAppName) -{ - return NS_GetNavigatorAppName(aAppName); -} - -/** - * JS property navigator.language, exposed to web content. - * Take first value from Accept-Languages (HTTP header), which is - * the "content language" freely set by the user in the Pref window. - * - * Do not use UI language (chosen app locale) here. - * See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers" - * - * "en", "en-US" and "i-cherokee" and "" are valid. - * Fallback in case of invalid pref should be "" (empty string), to - * let site do fallback, e.g. to site's local language. - */ -NS_IMETHODIMP -nsNavigator::GetLanguage(nsAString& aLanguage) -{ - // e.g. "de-de, en-us,en" - const nsAdoptingString& acceptLang = - Preferences::GetLocalizedString("intl.accept_languages"); - // take everything before the first "," or ";", without trailing space - nsCharSeparatedTokenizer langTokenizer(acceptLang, ','); - const nsSubstring &firstLangPart = langTokenizer.nextToken(); - nsCharSeparatedTokenizer qTokenizer(firstLangPart, ';'); - aLanguage.Assign(qTokenizer.nextToken()); - - // checks and fixups - // replace "_" with "-", to avoid POSIX/Windows "en_US" notation - if (aLanguage.Length() > 2 && aLanguage[2] == PRUnichar('_')) - aLanguage.Replace(2, 1, PRUnichar('-')); // TODO replace all - // use uppercase for country part, e.g. "en-US", not "en-us", see BCP47 - // only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe" - if (aLanguage.Length() > 2) - { - nsCharSeparatedTokenizer localeTokenizer(aLanguage, '-'); - PRInt32 pos = 0; - bool first = true; - while (localeTokenizer.hasMoreTokens()) - { - const nsSubstring &code = localeTokenizer.nextToken(); - if (code.Length() == 2 && !first) - { - nsAutoString upper(code); - ::ToUpperCase(upper); - aLanguage.Replace(pos, code.Length(), upper); - } - pos += code.Length() + 1; // 1 is the separator - if (first) - first = false; - } - } - return NS_OK; -} - -NS_IMETHODIMP -nsNavigator::GetPlatform(nsAString& aPlatform) -{ - return NS_GetNavigatorPlatform(aPlatform); -} - -NS_IMETHODIMP -nsNavigator::GetOscpu(nsAString& aOSCPU) -{ - if (!nsContentUtils::IsCallerTrustedForRead()) { - const nsAdoptingString& override = - Preferences::GetString("general.oscpu.override"); - - if (override) { - aOSCPU = override; - return NS_OK; - } - } - - nsresult rv; - nsCOMPtr - service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); - if (NS_SUCCEEDED(rv)) { - nsCAutoString oscpu; - rv = service->GetOscpu(oscpu); - CopyASCIItoUTF16(oscpu, aOSCPU); - } - - return rv; -} - -NS_IMETHODIMP -nsNavigator::GetVendor(nsAString& aVendor) -{ - aVendor.Truncate(); - return NS_OK; -} - - -NS_IMETHODIMP -nsNavigator::GetVendorSub(nsAString& aVendorSub) -{ - aVendorSub.Truncate(); - return NS_OK; -} - -NS_IMETHODIMP -nsNavigator::GetProduct(nsAString& aProduct) -{ - nsresult rv; - nsCOMPtr - service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); - if (NS_SUCCEEDED(rv)) { - nsCAutoString product; - rv = service->GetProduct(product); - CopyASCIItoUTF16(product, aProduct); - } - - return rv; -} - -NS_IMETHODIMP -nsNavigator::GetProductSub(nsAString& aProductSub) -{ - if (!nsContentUtils::IsCallerTrustedForRead()) { - const nsAdoptingString& override = - Preferences::GetString("general.productSub.override"); - - if (override) { - aProductSub = override; - return NS_OK; - } - - // 'general.useragent.productSub' backwards compatible with 1.8 branch. - const nsAdoptingString& override2 = - Preferences::GetString("general.useragent.productSub"); - - if (override2) { - aProductSub = override2; - return NS_OK; - } - } - - nsresult rv; - nsCOMPtr - service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv)); - if (NS_SUCCEEDED(rv)) { - nsCAutoString productSub; - rv = service->GetProductSub(productSub); - CopyASCIItoUTF16(productSub, aProductSub); - } - - return rv; -} - -NS_IMETHODIMP -nsNavigator::GetMimeTypes(nsIDOMMimeTypeArray **aMimeTypes) -{ - if (!mMimeTypes) { - mMimeTypes = new nsMimeTypeArray(this); - if (!mMimeTypes) { - return NS_ERROR_OUT_OF_MEMORY; - } - } - - NS_ADDREF(*aMimeTypes = mMimeTypes); - - return NS_OK; -} - -NS_IMETHODIMP -nsNavigator::GetPlugins(nsIDOMPluginArray **aPlugins) -{ - if (!mPlugins) { - mPlugins = new nsPluginArray(this, mDocShell); - if (!mPlugins) { - return NS_ERROR_OUT_OF_MEMORY; - } - } - - NS_ADDREF(*aPlugins = mPlugins); - - return NS_OK; -} - -// values for the network.cookie.cookieBehavior pref are documented in -// nsCookieService.cpp. -#define COOKIE_BEHAVIOR_REJECT 2 - -NS_IMETHODIMP -nsNavigator::GetCookieEnabled(bool *aCookieEnabled) -{ - *aCookieEnabled = - (Preferences::GetInt("network.cookie.cookieBehavior", - COOKIE_BEHAVIOR_REJECT) != COOKIE_BEHAVIOR_REJECT); - - // Check whether an exception overrides the global cookie behavior - // Note that the code for getting the URI here matches that in - // nsHTMLDocument::SetCookie. - nsCOMPtr doc = do_GetInterface(mDocShell); - if (!doc) { - return NS_OK; - } - - nsCOMPtr codebaseURI; - doc->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI)); - - if (!codebaseURI) { - // Not a codebase, so technically can't set cookies, but let's - // just return the default value. - return NS_OK; - } - - nsCOMPtr permMgr = - do_GetService(NS_COOKIEPERMISSION_CONTRACTID); - NS_ENSURE_TRUE(permMgr, NS_OK); - - // Pass null for the channel, just like the cookie service does - nsCookieAccess access; - nsresult rv = permMgr->CanAccess(codebaseURI, nsnull, &access); - NS_ENSURE_SUCCESS(rv, NS_OK); - - if (access != nsICookiePermission::ACCESS_DEFAULT) { - *aCookieEnabled = access != nsICookiePermission::ACCESS_DENY; - } - - return NS_OK; -} - -NS_IMETHODIMP -nsNavigator::GetOnLine(bool* aOnline) -{ - NS_PRECONDITION(aOnline, "Null out param"); - - *aOnline = !NS_IsOffline(); - return NS_OK; -} - -NS_IMETHODIMP -nsNavigator::GetBuildID(nsAString& aBuildID) -{ - if (!nsContentUtils::IsCallerTrustedForRead()) { - const nsAdoptingString& override = - Preferences::GetString("general.buildID.override"); - - if (override) { - aBuildID = override; - return NS_OK; - } - } - - nsCOMPtr appInfo = - do_GetService("@mozilla.org/xre/app-info;1"); - if (!appInfo) - return NS_ERROR_NOT_IMPLEMENTED; - - nsCAutoString buildID; - nsresult rv = appInfo->GetAppBuildID(buildID); - if (NS_FAILED(rv)) - return rv; - - aBuildID.Truncate(); - AppendASCIItoUTF16(buildID, aBuildID); - return NS_OK; -} - -NS_IMETHODIMP -nsNavigator::GetDoNotTrack(nsAString &aResult) -{ - if (gDoNotTrackEnabled) { - aResult.AssignLiteral("yes"); - } - else { - aResult.AssignLiteral("unspecified"); - } - return NS_OK; -} - -NS_IMETHODIMP -nsNavigator::JavaEnabled(bool *aReturn) -{ - Telemetry::AutoTimer telemetryTimer; - // Return true if we have a handler for "application/x-java-vm", - // otherwise return false. - *aReturn = false; - - if (!mMimeTypes) { - mMimeTypes = new nsMimeTypeArray(this); - if (!mMimeTypes) - return NS_ERROR_OUT_OF_MEMORY; - } - - RefreshMIMEArray(); - - PRUint32 count; - mMimeTypes->GetLength(&count); - for (PRUint32 i = 0; i < count; i++) { - nsresult rv; - nsIDOMMimeType* type = mMimeTypes->GetItemAt(i, &rv); - nsAutoString mimeString; - if (type && NS_SUCCEEDED(type->GetType(mimeString))) { - if (mimeString.EqualsLiteral("application/x-java-vm")) { - *aReturn = true; - break; - } - } - } - - return NS_OK; -} - -void -nsNavigator::LoadingNewDocument() -{ - // Release these so that they will be recreated for the - // new document (if requested). The plugins or mime types - // arrays may have changed. See bug 150087. - if (mMimeTypes) { - mMimeTypes->Invalidate(); - mMimeTypes = nsnull; - } - - if (mPlugins) { - mPlugins->Invalidate(); - mPlugins = nsnull; - } - - if (mGeolocation) - { - mGeolocation->Shutdown(); - mGeolocation = nsnull; - } - - if (mNotification) - { - mNotification->Shutdown(); - mNotification = nsnull; - } - -} - -nsresult -nsNavigator::RefreshMIMEArray() -{ - nsresult rv = NS_OK; - if (mMimeTypes) - rv = mMimeTypes->Refresh(); - return rv; -} - -bool -nsNavigator::HasDesktopNotificationSupport() -{ - return Preferences::GetBool("notification.feature.enabled", false); -} - -//***************************************************************************** -// nsNavigator::nsIDOMClientInformation -//***************************************************************************** - -NS_IMETHODIMP -nsNavigator::RegisterContentHandler(const nsAString& aMIMEType, - const nsAString& aURI, - const nsAString& aTitle) -{ - nsCOMPtr registrar = - do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID); - if (registrar && mDocShell) { - nsCOMPtr contentDOMWindow(do_GetInterface(mDocShell)); - if (contentDOMWindow) - return registrar->RegisterContentHandler(aMIMEType, aURI, aTitle, - contentDOMWindow); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsNavigator::RegisterProtocolHandler(const nsAString& aProtocol, - const nsAString& aURI, - const nsAString& aTitle) -{ - nsCOMPtr registrar = - do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID); - if (registrar && mDocShell) { - nsCOMPtr contentDOMWindow(do_GetInterface(mDocShell)); - if (contentDOMWindow) - return registrar->RegisterProtocolHandler(aProtocol, aURI, aTitle, - contentDOMWindow); - } - - return NS_OK; -} - - -NS_IMETHODIMP -nsNavigator::MozIsLocallyAvailable(const nsAString &aURI, - bool aWhenOffline, - bool *aIsAvailable) -{ - nsCOMPtr uri; - nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI); - NS_ENSURE_SUCCESS(rv, rv); - - // This method of checking the cache will only work for http/https urls - bool match; - rv = uri->SchemeIs("http", &match); - NS_ENSURE_SUCCESS(rv, rv); - if (!match) { - rv = uri->SchemeIs("https", &match); - NS_ENSURE_SUCCESS(rv, rv); - if (!match) return NS_ERROR_DOM_BAD_URI; - } - - // Same origin check - nsCOMPtr stack = do_GetService(sJSStackContractID); - NS_ENSURE_TRUE(stack, NS_ERROR_FAILURE); - - JSContext *cx = nsnull; - rv = stack->Peek(&cx); - NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE); - - rv = nsContentUtils::GetSecurityManager()->CheckSameOrigin(cx, uri); - NS_ENSURE_SUCCESS(rv, rv); - - // these load flags cause an error to be thrown if there is no - // valid cache entry, and skip the load if there is. - // if the cache is busy, assume that it is not yet available rather - // than waiting for it to become available. - PRUint32 loadFlags = nsIChannel::INHIBIT_CACHING | - nsICachingChannel::LOAD_NO_NETWORK_IO | - nsICachingChannel::LOAD_ONLY_IF_MODIFIED | - nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY; - - if (aWhenOffline) { - loadFlags |= nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE | - nsICachingChannel::LOAD_ONLY_FROM_CACHE | - nsIRequest::LOAD_FROM_CACHE; - } - - nsCOMPtr channel; - rv = NS_NewChannel(getter_AddRefs(channel), uri, - nsnull, nsnull, nsnull, loadFlags); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr stream; - rv = channel->Open(getter_AddRefs(stream)); - NS_ENSURE_SUCCESS(rv, rv); - - stream->Close(); - - nsresult status; - rv = channel->GetStatus(&status); - NS_ENSURE_SUCCESS(rv, rv); - - if (NS_SUCCEEDED(status)) { - nsCOMPtr httpChannel = do_QueryInterface(channel); - rv = httpChannel->GetRequestSucceeded(aIsAvailable); - NS_ENSURE_SUCCESS(rv, rv); - } else { - *aIsAvailable = false; - } - - return NS_OK; -} - -//***************************************************************************** -// nsNavigator::nsIDOMNavigatorGeolocation -//***************************************************************************** - -NS_IMETHODIMP nsNavigator::GetGeolocation(nsIDOMGeoGeolocation **_retval) -{ - NS_ENSURE_ARG_POINTER(_retval); - *_retval = nsnull; - - if (!Preferences::GetBool("geo.enabled", true)) - return NS_OK; - - if (mGeolocation) { - NS_ADDREF(*_retval = mGeolocation); - return NS_OK; - } - - if (!mDocShell) - return NS_ERROR_FAILURE; - - nsCOMPtr contentDOMWindow(do_GetInterface(mDocShell)); - if (!contentDOMWindow) - return NS_ERROR_FAILURE; - - mGeolocation = new nsGeolocation(); - if (!mGeolocation) - return NS_ERROR_FAILURE; - - if (NS_FAILED(mGeolocation->Init(contentDOMWindow))) { - mGeolocation = nsnull; - return NS_ERROR_FAILURE; - } - - NS_ADDREF(*_retval = mGeolocation); - return NS_OK; -} - - -//***************************************************************************** -// nsNavigator::nsIDOMNavigatorDesktopNotification -//***************************************************************************** - -NS_IMETHODIMP nsNavigator::GetMozNotification(nsIDOMDesktopNotificationCenter **aRetVal) -{ - NS_ENSURE_ARG_POINTER(aRetVal); - *aRetVal = nsnull; - - if (mNotification) { - NS_ADDREF(*aRetVal = mNotification); - return NS_OK; - } - - nsCOMPtr window(do_GetInterface(mDocShell)); - NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); - - nsCOMPtr document = do_GetInterface(mDocShell); - NS_ENSURE_TRUE(document, NS_ERROR_FAILURE); - - nsIScriptGlobalObject *sgo = document->GetScopeObject(); - NS_ENSURE_TRUE(sgo, NS_ERROR_FAILURE); - - nsIScriptContext *scx = sgo->GetContext(); - NS_ENSURE_TRUE(scx, NS_ERROR_FAILURE); - - mNotification = new nsDesktopNotificationCenter(window->GetCurrentInnerWindow(), - scx); - if (!mNotification) { - return NS_ERROR_FAILURE; - } - - NS_ADDREF(*aRetVal = mNotification); - return NS_OK; -} - #define EVENT(name_, id_, type_, struct_) \ NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx, \ jsval *vp) { \ @@ -11479,20 +10730,3 @@ NS_IMETHODIMP nsNavigator::GetMozNotification(nsIDOMDesktopNotificationCenter ** #undef WINDOW_ONLY_EVENT #undef EVENT -PRInt64 -nsNavigator::SizeOf() const -{ - PRInt64 size = sizeof(*this); - - // TODO: add SizeOf() to nsMimeTypeArray, bug 674113. - size += mMimeTypes ? sizeof(*mMimeTypes.get()) : 0; - // TODO: add SizeOf() to nsPluginArray, bug 674114. - size += mPlugins ? sizeof(*mPlugins.get()) : 0; - // TODO: add SizeOf() to nsGeolocation, bug 674115. - size += mGeolocation ? sizeof(*mGeolocation.get()) : 0; - // TODO: add SizeOf() to nsDesktopNotificationCenter, bug 674116. - size += mNotification ? sizeof(*mNotification.get()) : 0; - - return size; -} - diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 080859176564..8a10253427ea 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -61,11 +61,7 @@ #include "nsIBrowserDOMWindow.h" #include "nsIDocShellTreeOwner.h" #include "nsIDocShellTreeItem.h" -#include "nsIDOMClientInformation.h" #include "nsIDOMEventTarget.h" -#include "nsIDOMNavigator.h" -#include "nsIDOMNavigatorGeolocation.h" -#include "nsIDOMNavigatorDesktopNotification.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIDOMJSWindow.h" @@ -85,8 +81,6 @@ #include "nsIDOMCrypto.h" #endif #include "nsIPrincipal.h" -#include "nsPluginArray.h" -#include "nsMimeTypeArray.h" #include "nsIXPCScriptable.h" #include "nsPoint.h" #include "nsSize.h" @@ -130,7 +124,6 @@ class nsIControllers; class nsBarProp; class nsLocation; -class nsNavigator; class nsScreen; class nsHistory; class nsPerformance; @@ -143,14 +136,18 @@ class PostMessageEvent; class nsRunnable; class nsDOMOfflineResourceList; -class nsGeolocation; -class nsDesktopNotificationCenter; class nsDOMMozURLProperty; #ifdef MOZ_DISABLE_DOMCRYPTO class nsIDOMCrypto; #endif +namespace mozilla { +namespace dom { +class Navigator; +} // namespace dom +} // namespace mozilla + extern nsresult NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow, bool *aIsInterval, @@ -290,6 +287,7 @@ public: typedef mozilla::TimeStamp TimeStamp; typedef mozilla::TimeDuration TimeDuration; + typedef mozilla::dom::Navigator Navigator; typedef nsDataHashtable WindowByIdTable; // public methods @@ -906,7 +904,7 @@ protected: nsCOMPtr mArguments; nsCOMPtr mArgumentsLast; nsCOMPtr mArgumentsOrigin; - nsRefPtr mNavigator; + nsRefPtr mNavigator; nsRefPtr mScreen; nsRefPtr mPerformance; nsRefPtr mFrames; @@ -1073,52 +1071,6 @@ protected: nsCOMPtr mReturnValue; }; - -//***************************************************************************** -// nsNavigator: Script "navigator" object -//***************************************************************************** - -class nsNavigator : public nsIDOMNavigator, - public nsIDOMClientInformation, - public nsIDOMNavigatorGeolocation, - public nsIDOMNavigatorDesktopNotification -{ -public: - nsNavigator(nsIDocShell *aDocShell); - virtual ~nsNavigator(); - - NS_DECL_ISUPPORTS - NS_DECL_NSIDOMNAVIGATOR - NS_DECL_NSIDOMCLIENTINFORMATION - NS_DECL_NSIDOMNAVIGATORGEOLOCATION - NS_DECL_NSIDOMNAVIGATORDESKTOPNOTIFICATION - - void SetDocShell(nsIDocShell *aDocShell); - nsIDocShell *GetDocShell() - { - return mDocShell; - } - - void LoadingNewDocument(); - nsresult RefreshMIMEArray(); - - static bool HasDesktopNotificationSupport(); - - PRInt64 SizeOf() const; - -protected: - nsRefPtr mMimeTypes; - nsRefPtr mPlugins; - nsRefPtr mGeolocation; - nsRefPtr mNotification; - nsIDocShell* mDocShell; // weak reference -}; - -nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent); -nsresult NS_GetNavigatorPlatform(nsAString& aPlatform); -nsresult NS_GetNavigatorAppVersion(nsAString& aAppVersion); -nsresult NS_GetNavigatorAppName(nsAString& aAppName); - /* factory function */ nsresult NS_NewScriptGlobalObject(bool aIsChrome, bool aIsModalContentWindow, diff --git a/dom/base/nsPluginArray.cpp b/dom/base/nsPluginArray.cpp index 42582ddb5b33..e9edda007650 100644 --- a/dom/base/nsPluginArray.cpp +++ b/dom/base/nsPluginArray.cpp @@ -38,7 +38,7 @@ #include "nsPluginArray.h" #include "nsMimeTypeArray.h" -#include "nsGlobalWindow.h" +#include "Navigator.h" #include "nsIScriptGlobalObject.h" #include "nsIDOMNavigator.h" #include "nsIDOMMimeType.h" @@ -50,7 +50,10 @@ #include "nsContentUtils.h" #include "nsPluginHost.h" -nsPluginArray::nsPluginArray(nsNavigator* navigator, +using namespace mozilla; +using namespace mozilla::dom; + +nsPluginArray::nsPluginArray(Navigator* navigator, nsIDocShell *aDocShell) { nsresult rv; diff --git a/dom/base/nsPluginArray.h b/dom/base/nsPluginArray.h index 7d4674eaf335..a4bcda465563 100644 --- a/dom/base/nsPluginArray.h +++ b/dom/base/nsPluginArray.h @@ -44,15 +44,20 @@ #include "nsIPluginHost.h" #include "nsIURL.h" -class nsNavigator; +namespace mozilla { +namespace dom { +class Navigator; +} // namespace dom +} // namespace mozilla + class nsIDocShell; -// NB: Due to weak references, nsNavigator has intimate knowledge of our +// NB: Due to weak references, Navigator has intimate knowledge of our // internals. class nsPluginArray : public nsIDOMPluginArray { public: - nsPluginArray(nsNavigator* navigator, nsIDocShell *aDocShell); + nsPluginArray(mozilla::dom::Navigator* navigator, nsIDocShell *aDocShell); virtual ~nsPluginArray(); NS_DECL_ISUPPORTS @@ -91,7 +96,7 @@ public: void Invalidate(); protected: - nsNavigator* mNavigator; + mozilla::dom::Navigator* mNavigator; nsCOMPtr mPluginHost; PRUint32 mPluginCount; nsIDOMPlugin** mPluginArray; diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 82e6069d658c..04158ed8b15f 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -56,7 +56,7 @@ #include "mozilla/Preferences.h" #include "nsContentUtils.h" #include "nsDOMJSUtils.h" -#include "nsGlobalWindow.h" +#include #include "nsNetUtil.h" #include "nsServiceManagerUtils.h" #include "nsThreadUtils.h" diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp index 324323da9a24..645d48eee0da 100644 --- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -90,6 +90,7 @@ #include "nsSVGUtils.h" #include "nsMathMLAtoms.h" #include "nsMathMLOperators.h" +#include "Navigator.h" #ifdef MOZ_XUL #include "nsXULPopupManager.h" @@ -160,6 +161,7 @@ nsLayoutStatics::Initialize() } nsGlobalWindow::Init(); + dom::Navigator::Init(); rv = nsContentUtils::Init(); if (NS_FAILED(rv)) {