michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 sw=2 et tw=78: */ 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 "nsChromeRegistry.h" michael@0: #include "nsChromeRegistryChrome.h" michael@0: #include "nsChromeRegistryContent.h" michael@0: michael@0: #include "prprf.h" michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsError.h" michael@0: #include "nsEscape.h" michael@0: #include "nsNetUtil.h" michael@0: #include "nsString.h" michael@0: michael@0: #include "nsCSSStyleSheet.h" michael@0: #include "nsIConsoleService.h" michael@0: #include "nsIDocument.h" michael@0: #include "nsIDOMDocument.h" michael@0: #include "nsIDOMLocation.h" michael@0: #include "nsIDOMWindowCollection.h" michael@0: #include "nsIDOMWindow.h" michael@0: #include "nsIObserverService.h" michael@0: #include "nsIPresShell.h" michael@0: #include "nsIScriptError.h" michael@0: #include "nsIWindowMediator.h" michael@0: #include "mozilla/dom/URL.h" michael@0: michael@0: nsChromeRegistry* nsChromeRegistry::gChromeRegistry; michael@0: using mozilla::dom::IsChromeURI; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: void michael@0: nsChromeRegistry::LogMessage(const char* aMsg, ...) michael@0: { michael@0: nsCOMPtr console michael@0: (do_GetService(NS_CONSOLESERVICE_CONTRACTID)); michael@0: if (!console) michael@0: return; michael@0: michael@0: va_list args; michael@0: va_start(args, aMsg); michael@0: char* formatted = PR_vsmprintf(aMsg, args); michael@0: va_end(args); michael@0: if (!formatted) michael@0: return; michael@0: michael@0: console->LogStringMessage(NS_ConvertUTF8toUTF16(formatted).get()); michael@0: PR_smprintf_free(formatted); michael@0: } michael@0: michael@0: void michael@0: nsChromeRegistry::LogMessageWithContext(nsIURI* aURL, uint32_t aLineNumber, uint32_t flags, michael@0: const char* aMsg, ...) michael@0: { michael@0: nsresult rv; michael@0: michael@0: nsCOMPtr console michael@0: (do_GetService(NS_CONSOLESERVICE_CONTRACTID)); michael@0: michael@0: nsCOMPtr error michael@0: (do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); michael@0: if (!console || !error) michael@0: return; michael@0: michael@0: va_list args; michael@0: va_start(args, aMsg); michael@0: char* formatted = PR_vsmprintf(aMsg, args); michael@0: va_end(args); michael@0: if (!formatted) michael@0: return; michael@0: michael@0: nsCString spec; michael@0: if (aURL) michael@0: aURL->GetSpec(spec); michael@0: michael@0: rv = error->Init(NS_ConvertUTF8toUTF16(formatted), michael@0: NS_ConvertUTF8toUTF16(spec), michael@0: EmptyString(), michael@0: aLineNumber, 0, flags, "chrome registration"); michael@0: PR_smprintf_free(formatted); michael@0: michael@0: if (NS_FAILED(rv)) michael@0: return; michael@0: michael@0: console->LogMessage(error); michael@0: } michael@0: michael@0: nsChromeRegistry::~nsChromeRegistry() michael@0: { michael@0: gChromeRegistry = nullptr; michael@0: } michael@0: michael@0: NS_INTERFACE_MAP_BEGIN(nsChromeRegistry) michael@0: NS_INTERFACE_MAP_ENTRY(nsIChromeRegistry) michael@0: NS_INTERFACE_MAP_ENTRY(nsIXULChromeRegistry) michael@0: NS_INTERFACE_MAP_ENTRY(nsIToolkitChromeRegistry) michael@0: #ifdef MOZ_XUL michael@0: NS_INTERFACE_MAP_ENTRY(nsIXULOverlayProvider) michael@0: #endif michael@0: NS_INTERFACE_MAP_ENTRY(nsIObserver) michael@0: NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) michael@0: NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChromeRegistry) michael@0: NS_INTERFACE_MAP_END michael@0: michael@0: NS_IMPL_ADDREF(nsChromeRegistry) michael@0: NS_IMPL_RELEASE(nsChromeRegistry) michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // nsIChromeRegistry methods: michael@0: michael@0: already_AddRefed michael@0: nsChromeRegistry::GetService() michael@0: { michael@0: if (!gChromeRegistry) michael@0: { michael@0: // We don't actually want this ref, we just want the service to michael@0: // initialize if it hasn't already. michael@0: nsCOMPtr reg( michael@0: do_GetService(NS_CHROMEREGISTRY_CONTRACTID)); michael@0: if (!gChromeRegistry) michael@0: return nullptr; michael@0: } michael@0: nsCOMPtr registry = gChromeRegistry; michael@0: return registry.forget(); michael@0: } michael@0: michael@0: nsresult michael@0: nsChromeRegistry::Init() michael@0: { michael@0: // This initialization process is fairly complicated and may cause reentrant michael@0: // getservice calls to resolve chrome URIs (especially locale files). We michael@0: // don't want that, so we inform the protocol handler about our existence michael@0: // before we are actually fully initialized. michael@0: gChromeRegistry = this; michael@0: michael@0: mInitialized = true; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsChromeRegistry::GetProviderAndPath(nsIURL* aChromeURL, michael@0: nsACString& aProvider, nsACString& aPath) michael@0: { michael@0: nsresult rv; michael@0: michael@0: #ifdef DEBUG michael@0: bool isChrome; michael@0: aChromeURL->SchemeIs("chrome", &isChrome); michael@0: NS_ASSERTION(isChrome, "Non-chrome URI?"); michael@0: #endif michael@0: michael@0: nsAutoCString path; michael@0: rv = aChromeURL->GetPath(path); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (path.Length() < 3) { michael@0: LogMessage("Invalid chrome URI: %s", path.get()); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: path.SetLength(nsUnescapeCount(path.BeginWriting())); michael@0: NS_ASSERTION(path.First() == '/', "Path should always begin with a slash!"); michael@0: michael@0: int32_t slash = path.FindChar('/', 1); michael@0: if (slash == 1) { michael@0: LogMessage("Invalid chrome URI: %s", path.get()); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: if (slash == -1) { michael@0: aPath.Truncate(); michael@0: } michael@0: else { michael@0: if (slash == (int32_t) path.Length() - 1) michael@0: aPath.Truncate(); michael@0: else michael@0: aPath.Assign(path.get() + slash + 1, path.Length() - slash - 1); michael@0: michael@0: --slash; michael@0: } michael@0: michael@0: aProvider.Assign(path.get() + 1, slash); michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: nsresult michael@0: nsChromeRegistry::Canonify(nsIURL* aChromeURL) michael@0: { michael@0: NS_NAMED_LITERAL_CSTRING(kSlash, "/"); michael@0: michael@0: nsresult rv; michael@0: michael@0: nsAutoCString provider, path; michael@0: rv = GetProviderAndPath(aChromeURL, provider, path); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (path.IsEmpty()) { michael@0: nsAutoCString package; michael@0: rv = aChromeURL->GetHost(package); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // we re-use the "path" local string to build a new URL path michael@0: path.Assign(kSlash + provider + kSlash + package); michael@0: if (provider.EqualsLiteral("content")) { michael@0: path.AppendLiteral(".xul"); michael@0: } michael@0: else if (provider.EqualsLiteral("locale")) { michael@0: path.AppendLiteral(".dtd"); michael@0: } michael@0: else if (provider.EqualsLiteral("skin")) { michael@0: path.AppendLiteral(".css"); michael@0: } michael@0: else { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: aChromeURL->SetPath(path); michael@0: } michael@0: else { michael@0: // prevent directory traversals ("..") michael@0: // path is already unescaped once, but uris can get unescaped twice michael@0: const char* pos = path.BeginReading(); michael@0: const char* end = path.EndReading(); michael@0: while (pos < end) { michael@0: switch (*pos) { michael@0: case ':': michael@0: return NS_ERROR_DOM_BAD_URI; michael@0: case '.': michael@0: if (pos[1] == '.') michael@0: return NS_ERROR_DOM_BAD_URI; michael@0: break; michael@0: case '%': michael@0: // chrome: URIs with double-escapes are trying to trick us. michael@0: // watch for %2e, and %25 in case someone triple unescapes michael@0: if (pos[1] == '2' && michael@0: ( pos[2] == 'e' || pos[2] == 'E' || michael@0: pos[2] == '5' )) michael@0: return NS_ERROR_DOM_BAD_URI; michael@0: break; michael@0: case '?': michael@0: case '#': michael@0: pos = end; michael@0: continue; michael@0: } michael@0: ++pos; michael@0: } michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsChromeRegistry::ConvertChromeURL(nsIURI* aChromeURI, nsIURI* *aResult) michael@0: { michael@0: nsresult rv; michael@0: NS_ASSERTION(aChromeURI, "null url!"); michael@0: michael@0: if (mOverrideTable.Get(aChromeURI, aResult)) michael@0: return NS_OK; michael@0: michael@0: nsCOMPtr chromeURL (do_QueryInterface(aChromeURI)); michael@0: NS_ENSURE_TRUE(chromeURL, NS_NOINTERFACE); michael@0: michael@0: nsAutoCString package, provider, path; michael@0: rv = chromeURL->GetHostPort(package); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = GetProviderAndPath(chromeURL, provider, path); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsIURI* baseURI = GetBaseURIFromPackage(package, provider, path); michael@0: michael@0: uint32_t flags; michael@0: rv = GetFlagsFromPackage(package, &flags); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: if (flags & PLATFORM_PACKAGE) { michael@0: #if defined(XP_WIN) michael@0: path.Insert("win/", 0); michael@0: #elif defined(XP_MACOSX) michael@0: path.Insert("mac/", 0); michael@0: #else michael@0: path.Insert("unix/", 0); michael@0: #endif michael@0: } michael@0: michael@0: if (!baseURI) { michael@0: LogMessage("No chrome package registered for chrome://%s/%s/%s", michael@0: package.get(), provider.get(), path.get()); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: return NS_NewURI(aResult, path, nullptr, baseURI); michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: michael@0: // theme stuff michael@0: michael@0: michael@0: static void FlushSkinBindingsForWindow(nsIDOMWindow* aWindow) michael@0: { michael@0: // Get the DOM document. michael@0: nsCOMPtr domDocument; michael@0: aWindow->GetDocument(getter_AddRefs(domDocument)); michael@0: if (!domDocument) michael@0: return; michael@0: michael@0: nsCOMPtr document = do_QueryInterface(domDocument); michael@0: if (!document) michael@0: return; michael@0: michael@0: // Annihilate all XBL bindings. michael@0: document->FlushSkinBindings(); michael@0: } michael@0: michael@0: // XXXbsmedberg: move this to nsIWindowMediator michael@0: NS_IMETHODIMP nsChromeRegistry::RefreshSkins() michael@0: { michael@0: nsCOMPtr windowMediator michael@0: (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID)); michael@0: if (!windowMediator) michael@0: return NS_OK; michael@0: michael@0: nsCOMPtr windowEnumerator; michael@0: windowMediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator)); michael@0: bool more; michael@0: windowEnumerator->HasMoreElements(&more); michael@0: while (more) { michael@0: nsCOMPtr protoWindow; michael@0: windowEnumerator->GetNext(getter_AddRefs(protoWindow)); michael@0: if (protoWindow) { michael@0: nsCOMPtr domWindow = do_QueryInterface(protoWindow); michael@0: if (domWindow) michael@0: FlushSkinBindingsForWindow(domWindow); michael@0: } michael@0: windowEnumerator->HasMoreElements(&more); michael@0: } michael@0: michael@0: FlushSkinCaches(); michael@0: michael@0: windowMediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator)); michael@0: windowEnumerator->HasMoreElements(&more); michael@0: while (more) { michael@0: nsCOMPtr protoWindow; michael@0: windowEnumerator->GetNext(getter_AddRefs(protoWindow)); michael@0: if (protoWindow) { michael@0: nsCOMPtr domWindow = do_QueryInterface(protoWindow); michael@0: if (domWindow) michael@0: RefreshWindow(domWindow); michael@0: } michael@0: windowEnumerator->HasMoreElements(&more); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: void michael@0: nsChromeRegistry::FlushSkinCaches() michael@0: { michael@0: nsCOMPtr obsSvc = michael@0: mozilla::services::GetObserverService(); michael@0: NS_ASSERTION(obsSvc, "Couldn't get observer service."); michael@0: michael@0: obsSvc->NotifyObservers(static_cast(this), michael@0: NS_CHROME_FLUSH_SKINS_TOPIC, nullptr); michael@0: } michael@0: michael@0: // XXXbsmedberg: move this to windowmediator michael@0: nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindow* aWindow) michael@0: { michael@0: // Deal with our subframes first. michael@0: nsCOMPtr frames; michael@0: aWindow->GetFrames(getter_AddRefs(frames)); michael@0: uint32_t length; michael@0: frames->GetLength(&length); michael@0: uint32_t j; michael@0: for (j = 0; j < length; j++) { michael@0: nsCOMPtr childWin; michael@0: frames->Item(j, getter_AddRefs(childWin)); michael@0: RefreshWindow(childWin); michael@0: } michael@0: michael@0: nsresult rv; michael@0: // Get the DOM document. michael@0: nsCOMPtr domDocument; michael@0: aWindow->GetDocument(getter_AddRefs(domDocument)); michael@0: if (!domDocument) michael@0: return NS_OK; michael@0: michael@0: nsCOMPtr document = do_QueryInterface(domDocument); michael@0: if (!document) michael@0: return NS_OK; michael@0: michael@0: // Deal with the agent sheets first. Have to do all the style sets by hand. michael@0: nsCOMPtr shell = document->GetShell(); michael@0: if (shell) { michael@0: // Reload only the chrome URL agent style sheets. michael@0: nsCOMArray agentSheets; michael@0: rv = shell->GetAgentStyleSheets(agentSheets); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsCOMArray newAgentSheets; michael@0: for (int32_t l = 0; l < agentSheets.Count(); ++l) { michael@0: nsIStyleSheet *sheet = agentSheets[l]; michael@0: michael@0: nsIURI* uri = sheet->GetSheetURI(); michael@0: michael@0: if (IsChromeURI(uri)) { michael@0: // Reload the sheet. michael@0: nsRefPtr newSheet; michael@0: rv = document->LoadChromeSheetSync(uri, true, michael@0: getter_AddRefs(newSheet)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: if (newSheet) { michael@0: rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE; michael@0: if (NS_FAILED(rv)) return rv; michael@0: } michael@0: } michael@0: else { // Just use the same sheet. michael@0: rv = newAgentSheets.AppendObject(sheet) ? NS_OK : NS_ERROR_FAILURE; michael@0: if (NS_FAILED(rv)) return rv; michael@0: } michael@0: } michael@0: michael@0: rv = shell->SetAgentStyleSheets(newAgentSheets); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: michael@0: // Build an array of nsIURIs of style sheets we need to load. michael@0: nsCOMArray oldSheets; michael@0: nsCOMArray newSheets; michael@0: michael@0: int32_t count = document->GetNumberOfStyleSheets(); michael@0: michael@0: // Iterate over the style sheets. michael@0: int32_t i; michael@0: for (i = 0; i < count; i++) { michael@0: // Get the style sheet michael@0: nsIStyleSheet *styleSheet = document->GetStyleSheetAt(i); michael@0: michael@0: if (!oldSheets.AppendObject(styleSheet)) { michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: } michael@0: } michael@0: michael@0: // Iterate over our old sheets and kick off a sync load of the new michael@0: // sheet if and only if it's a chrome URL. michael@0: for (i = 0; i < count; i++) { michael@0: nsRefPtr sheet = do_QueryObject(oldSheets[i]); michael@0: nsIURI* uri = sheet ? sheet->GetOriginalURI() : nullptr; michael@0: michael@0: if (uri && IsChromeURI(uri)) { michael@0: // Reload the sheet. michael@0: nsRefPtr newSheet; michael@0: // XXX what about chrome sheets that have a title or are disabled? This michael@0: // only works by sheer dumb luck. michael@0: document->LoadChromeSheetSync(uri, false, getter_AddRefs(newSheet)); michael@0: // Even if it's null, we put in in there. michael@0: newSheets.AppendObject(newSheet); michael@0: } michael@0: else { michael@0: // Just use the same sheet. michael@0: newSheets.AppendObject(sheet); michael@0: } michael@0: } michael@0: michael@0: // Now notify the document that multiple sheets have been added and removed. michael@0: document->UpdateStyleSheets(oldSheets, newSheets); michael@0: return NS_OK; michael@0: } michael@0: michael@0: void michael@0: nsChromeRegistry::FlushAllCaches() michael@0: { michael@0: nsCOMPtr obsSvc = michael@0: mozilla::services::GetObserverService(); michael@0: NS_ASSERTION(obsSvc, "Couldn't get observer service."); michael@0: michael@0: obsSvc->NotifyObservers((nsIChromeRegistry*) this, michael@0: NS_CHROME_FLUSH_TOPIC, nullptr); michael@0: } michael@0: michael@0: // xxxbsmedberg Move me to nsIWindowMediator michael@0: NS_IMETHODIMP michael@0: nsChromeRegistry::ReloadChrome() michael@0: { michael@0: UpdateSelectedLocale(); michael@0: FlushAllCaches(); michael@0: // Do a reload of all top level windows. michael@0: nsresult rv = NS_OK; michael@0: michael@0: // Get the window mediator michael@0: nsCOMPtr windowMediator michael@0: (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID)); michael@0: if (windowMediator) { michael@0: nsCOMPtr windowEnumerator; michael@0: michael@0: rv = windowMediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator)); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: // Get each dom window michael@0: bool more; michael@0: rv = windowEnumerator->HasMoreElements(&more); michael@0: if (NS_FAILED(rv)) return rv; michael@0: while (more) { michael@0: nsCOMPtr protoWindow; michael@0: rv = windowEnumerator->GetNext(getter_AddRefs(protoWindow)); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: nsCOMPtr domWindow = do_QueryInterface(protoWindow); michael@0: if (domWindow) { michael@0: nsCOMPtr location; michael@0: domWindow->GetLocation(getter_AddRefs(location)); michael@0: if (location) { michael@0: rv = location->Reload(false); michael@0: if (NS_FAILED(rv)) return rv; michael@0: } michael@0: } michael@0: } michael@0: rv = windowEnumerator->HasMoreElements(&more); michael@0: if (NS_FAILED(rv)) return rv; michael@0: } michael@0: } michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsChromeRegistry::AllowScriptsForPackage(nsIURI* aChromeURI, bool *aResult) michael@0: { michael@0: nsresult rv; michael@0: *aResult = false; michael@0: michael@0: #ifdef DEBUG michael@0: bool isChrome; michael@0: aChromeURI->SchemeIs("chrome", &isChrome); michael@0: NS_ASSERTION(isChrome, "Non-chrome URI passed to AllowScriptsForPackage!"); michael@0: #endif michael@0: michael@0: nsCOMPtr url (do_QueryInterface(aChromeURI)); michael@0: NS_ENSURE_TRUE(url, NS_NOINTERFACE); michael@0: michael@0: nsAutoCString provider, file; michael@0: rv = GetProviderAndPath(url, provider, file); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (!provider.EqualsLiteral("skin")) michael@0: *aResult = true; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsChromeRegistry::AllowContentToAccess(nsIURI *aURI, bool *aResult) michael@0: { michael@0: nsresult rv; michael@0: michael@0: *aResult = false; michael@0: michael@0: #ifdef DEBUG michael@0: bool isChrome; michael@0: aURI->SchemeIs("chrome", &isChrome); michael@0: NS_ASSERTION(isChrome, "Non-chrome URI passed to AllowContentToAccess!"); michael@0: #endif michael@0: michael@0: nsCOMPtr url = do_QueryInterface(aURI); michael@0: if (!url) { michael@0: NS_ERROR("Chrome URL doesn't implement nsIURL."); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: nsAutoCString package; michael@0: rv = url->GetHostPort(package); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: uint32_t flags; michael@0: rv = GetFlagsFromPackage(package, &flags); michael@0: michael@0: if (NS_SUCCEEDED(rv)) { michael@0: *aResult = !!(flags & CONTENT_ACCESSIBLE); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP_(bool) michael@0: nsChromeRegistry::WrappersEnabled(nsIURI *aURI) michael@0: { michael@0: nsCOMPtr chromeURL (do_QueryInterface(aURI)); michael@0: if (!chromeURL) michael@0: return false; michael@0: michael@0: bool isChrome = false; michael@0: nsresult rv = chromeURL->SchemeIs("chrome", &isChrome); michael@0: if (NS_FAILED(rv) || !isChrome) michael@0: return false; michael@0: michael@0: nsAutoCString package; michael@0: rv = chromeURL->GetHostPort(package); michael@0: if (NS_FAILED(rv)) michael@0: return false; michael@0: michael@0: uint32_t flags; michael@0: rv = GetFlagsFromPackage(package, &flags); michael@0: return NS_SUCCEEDED(rv) && (flags & XPCNATIVEWRAPPERS); michael@0: } michael@0: michael@0: already_AddRefed michael@0: nsChromeRegistry::GetSingleton() michael@0: { michael@0: if (gChromeRegistry) { michael@0: nsRefPtr registry = gChromeRegistry; michael@0: return registry.forget(); michael@0: } michael@0: michael@0: nsRefPtr cr; michael@0: if (GeckoProcessType_Content == XRE_GetProcessType()) michael@0: cr = new nsChromeRegistryContent(); michael@0: else michael@0: cr = new nsChromeRegistryChrome(); michael@0: michael@0: if (NS_FAILED(cr->Init())) michael@0: return nullptr; michael@0: michael@0: return cr.forget(); michael@0: }