123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "mozilla/dom/ContentParent.h"
- #include "RegistryMessageUtils.h"
- #include "nsResProtocolHandler.h"
- #include "nsChromeRegistryChrome.h"
- #if defined(XP_WIN)
- #include <windows.h>
- #endif
- #include "nsArrayEnumerator.h"
- #include "nsComponentManager.h"
- #include "nsEnumeratorUtils.h"
- #include "nsNetUtil.h"
- #include "nsStringEnumerator.h"
- #include "nsTextFormatter.h"
- #include "nsXPCOMCIDInternal.h"
- #include "mozilla/LookAndFeel.h"
- #include "mozilla/Unused.h"
- #include "nsICommandLine.h"
- #include "nsILocaleService.h"
- #include "nsIObserverService.h"
- #include "nsIPrefBranch.h"
- #include "nsIPrefService.h"
- #include "mozilla/Preferences.h"
- #include "nsIResProtocolHandler.h"
- #include "nsIScriptError.h"
- #include "nsIXPConnect.h"
- #include "nsIXULRuntime.h"
- #define UILOCALE_CMD_LINE_ARG "UILocale"
- #define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
- #define SELECTED_LOCALE_PREF "general.useragent.locale"
- #define SELECTED_SKIN_PREF "general.skins.selectedSkin"
- #define PACKAGE_OVERRIDE_BRANCH "chrome.override_package."
- using namespace mozilla;
- using mozilla::dom::ContentParent;
- using mozilla::dom::PContentParent;
- // We use a "best-fit" algorithm for matching locales and themes.
- // 1) the exact selected locale/theme
- // 2) (locales only) same language, different country
- // e.g. en-GB is the selected locale, only en-US is available
- // 3) any available locale/theme
- /**
- * Match the language-part of two lang-COUNTRY codes, hopefully but
- * not guaranteed to be in the form ab-CD or abz-CD. "ab" should also
- * work, any other garbage-in will produce undefined results as long
- * as it does not crash.
- */
- static bool
- LanguagesMatch(const nsACString& a, const nsACString& b)
- {
- if (a.Length() < 2 || b.Length() < 2)
- return false;
- nsACString::const_iterator as, ae, bs, be;
- a.BeginReading(as);
- a.EndReading(ae);
- b.BeginReading(bs);
- b.EndReading(be);
- while (*as == *bs) {
- if (*as == '-')
- return true;
- ++as; ++bs;
- // reached the end
- if (as == ae && bs == be)
- return true;
- // "a" is short
- if (as == ae)
- return (*bs == '-');
- // "b" is short
- if (bs == be)
- return (*as == '-');
- }
- return false;
- }
- nsChromeRegistryChrome::nsChromeRegistryChrome()
- : mProfileLoaded(false)
- , mDynamicRegistration(true)
- {
- }
- nsChromeRegistryChrome::~nsChromeRegistryChrome()
- {
- }
- nsresult
- nsChromeRegistryChrome::Init()
- {
- nsresult rv = nsChromeRegistry::Init();
- if (NS_FAILED(rv))
- return rv;
- mSelectedLocale = NS_LITERAL_CSTRING("en-US");
- mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0");
- bool safeMode = false;
- nsCOMPtr<nsIXULRuntime> xulrun (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
- if (xulrun)
- xulrun->GetInSafeMode(&safeMode);
- nsCOMPtr<nsIPrefService> prefserv (do_GetService(NS_PREFSERVICE_CONTRACTID));
- nsCOMPtr<nsIPrefBranch> prefs;
- if (prefserv) {
- if (safeMode) {
- prefserv->GetDefaultBranch(nullptr, getter_AddRefs(prefs));
- } else {
- prefs = do_QueryInterface(prefserv);
- }
- }
- if (!prefs) {
- NS_WARNING("Could not get pref service!");
- } else {
- nsXPIDLCString provider;
- rv = prefs->GetCharPref(SELECTED_SKIN_PREF, getter_Copies(provider));
- if (NS_SUCCEEDED(rv))
- mSelectedSkin = provider;
- SelectLocaleFromPref(prefs);
- rv = prefs->AddObserver(MATCH_OS_LOCALE_PREF, this, true);
- rv = prefs->AddObserver(SELECTED_LOCALE_PREF, this, true);
- rv = prefs->AddObserver(SELECTED_SKIN_PREF, this, true);
- }
- nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService();
- if (obsService) {
- obsService->AddObserver(this, "command-line-startup", true);
- obsService->AddObserver(this, "profile-initial-state", true);
- }
- return NS_OK;
- }
- NS_IMETHODIMP
- nsChromeRegistryChrome::CheckForOSAccessibility()
- {
- int32_t useAccessibilityTheme =
- LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme, 0);
- if (useAccessibilityTheme) {
- /* Set the skin to classic and remove pref observers */
- if (!mSelectedSkin.EqualsLiteral("classic/1.0")) {
- mSelectedSkin.AssignLiteral("classic/1.0");
- RefreshSkins();
- }
- nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
- if (prefs) {
- prefs->RemoveObserver(SELECTED_SKIN_PREF, this);
- }
- }
- return NS_OK;
- }
- NS_IMETHODIMP
- nsChromeRegistryChrome::GetLocalesForPackage(const nsACString& aPackage,
- nsIUTF8StringEnumerator* *aResult)
- {
- nsCString realpackage;
- nsresult rv = OverrideLocalePackage(aPackage, realpackage);
- if (NS_FAILED(rv))
- return rv;
- nsTArray<nsCString> *a = new nsTArray<nsCString>;
- if (!a)
- return NS_ERROR_OUT_OF_MEMORY;
- PackageEntry* entry;
- if (mPackagesHash.Get(realpackage, &entry)) {
- entry->locales.EnumerateToArray(a);
- }
- rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a);
- if (NS_FAILED(rv))
- delete a;
- return rv;
- }
- static nsresult
- getUILangCountry(nsACString& aUILang)
- {
- nsresult rv;
- nsCOMPtr<nsILocaleService> localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
- nsAutoString uiLang;
- rv = localeService->GetLocaleComponentForUserAgent(uiLang);
- NS_ENSURE_SUCCESS(rv, rv);
- CopyUTF16toUTF8(uiLang, aUILang);
- return NS_OK;
- }
- NS_IMETHODIMP
- nsChromeRegistryChrome::IsLocaleRTL(const nsACString& package, bool *aResult)
- {
- *aResult = false;
- nsAutoCString locale;
- GetSelectedLocale(package, false, locale);
- if (locale.Length() < 2)
- return NS_OK;
- *aResult = GetDirectionForLocale(locale);
- return NS_OK;
- }
- nsresult
- nsChromeRegistryChrome::GetSelectedLocale(const nsACString& aPackage,
- bool aAsBCP47,
- nsACString& aLocale)
- {
- nsCString realpackage;
- nsresult rv = OverrideLocalePackage(aPackage, realpackage);
- if (NS_FAILED(rv))
- return rv;
- PackageEntry* entry;
- if (!mPackagesHash.Get(realpackage, &entry))
- return NS_ERROR_FILE_NOT_FOUND;
- aLocale = entry->locales.GetSelected(mSelectedLocale, nsProviderArray::LOCALE);
- if (aLocale.IsEmpty())
- return NS_ERROR_FAILURE;
- if (aAsBCP47) {
- SanitizeForBCP47(aLocale);
- }
- return NS_OK;
- }
- nsresult
- nsChromeRegistryChrome::OverrideLocalePackage(const nsACString& aPackage,
- nsACString& aOverride)
- {
- const nsACString& pref = NS_LITERAL_CSTRING(PACKAGE_OVERRIDE_BRANCH) + aPackage;
- nsAdoptingCString override = mozilla::Preferences::GetCString(PromiseFlatCString(pref).get());
- if (override) {
- aOverride = override;
- }
- else {
- aOverride = aPackage;
- }
- return NS_OK;
- }
- nsresult
- nsChromeRegistryChrome::SelectLocaleFromPref(nsIPrefBranch* prefs)
- {
- nsresult rv;
- bool matchOSLocale = false;
- rv = prefs->GetBoolPref(MATCH_OS_LOCALE_PREF, &matchOSLocale);
- if (NS_SUCCEEDED(rv) && matchOSLocale) {
- // compute lang and region code only when needed!
- nsAutoCString uiLocale;
- rv = getUILangCountry(uiLocale);
- if (NS_SUCCEEDED(rv))
- mSelectedLocale = uiLocale;
- }
- else {
- nsXPIDLCString provider;
- rv = prefs->GetCharPref(SELECTED_LOCALE_PREF, getter_Copies(provider));
- if (NS_SUCCEEDED(rv)) {
- mSelectedLocale = provider;
- }
- }
- if (NS_FAILED(rv))
- NS_ERROR("Couldn't select locale from pref!");
- return rv;
- }
- NS_IMETHODIMP
- nsChromeRegistryChrome::Observe(nsISupports *aSubject, const char *aTopic,
- const char16_t *someData)
- {
- nsresult rv = NS_OK;
- if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
- nsCOMPtr<nsIPrefBranch> prefs (do_QueryInterface(aSubject));
- NS_ASSERTION(prefs, "Bad observer call!");
- NS_ConvertUTF16toUTF8 pref(someData);
- if (pref.EqualsLiteral(MATCH_OS_LOCALE_PREF) ||
- pref.EqualsLiteral(SELECTED_LOCALE_PREF)) {
- rv = UpdateSelectedLocale();
- if (NS_SUCCEEDED(rv) && mProfileLoaded)
- FlushAllCaches();
- }
- else if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
- nsXPIDLCString provider;
- rv = prefs->GetCharPref(pref.get(), getter_Copies(provider));
- if (NS_FAILED(rv)) {
- NS_ERROR("Couldn't get new skin pref!");
- return rv;
- }
- mSelectedSkin = provider;
- RefreshSkins();
- } else {
- NS_ERROR("Unexpected pref!");
- }
- }
- else if (!strcmp("command-line-startup", aTopic)) {
- nsCOMPtr<nsICommandLine> cmdLine (do_QueryInterface(aSubject));
- if (cmdLine) {
- nsAutoString uiLocale;
- rv = cmdLine->HandleFlagWithParam(NS_LITERAL_STRING(UILOCALE_CMD_LINE_ARG),
- false, uiLocale);
- if (NS_SUCCEEDED(rv) && !uiLocale.IsEmpty()) {
- CopyUTF16toUTF8(uiLocale, mSelectedLocale);
- nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
- if (prefs) {
- prefs->RemoveObserver(SELECTED_LOCALE_PREF, this);
- }
- }
- }
- }
- else if (!strcmp("profile-initial-state", aTopic)) {
- mProfileLoaded = true;
- }
- else {
- NS_ERROR("Unexpected observer topic!");
- }
- return rv;
- }
- NS_IMETHODIMP
- nsChromeRegistryChrome::CheckForNewChrome()
- {
- mPackagesHash.Clear();
- mOverlayHash.Clear();
- mStyleHash.Clear();
- mOverrideTable.Clear();
- mDynamicRegistration = false;
- nsComponentManagerImpl::gComponentManager->RereadChromeManifests();
- mDynamicRegistration = true;
- SendRegisteredChrome(nullptr);
- return NS_OK;
- }
- nsresult nsChromeRegistryChrome::UpdateSelectedLocale()
- {
- nsresult rv = NS_OK;
- nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
- if (prefs) {
- rv = SelectLocaleFromPref(prefs);
- if (NS_SUCCEEDED(rv)) {
- nsCOMPtr<nsIObserverService> obsSvc =
- mozilla::services::GetObserverService();
- NS_ASSERTION(obsSvc, "Couldn't get observer service.");
- obsSvc->NotifyObservers((nsIChromeRegistry*) this,
- "selected-locale-has-changed", nullptr);
- }
- }
- return rv;
- }
- static void
- SerializeURI(nsIURI* aURI,
- SerializedURI& aSerializedURI)
- {
- if (!aURI)
- return;
- aURI->GetSpec(aSerializedURI.spec);
- aURI->GetOriginCharset(aSerializedURI.charset);
- }
- void
- nsChromeRegistryChrome::SendRegisteredChrome(
- mozilla::dom::PContentParent* aParent)
- {
- InfallibleTArray<ChromePackage> packages;
- InfallibleTArray<SubstitutionMapping> resources;
- InfallibleTArray<OverrideMapping> overrides;
- for (auto iter = mPackagesHash.Iter(); !iter.Done(); iter.Next()) {
- ChromePackage chromePackage;
- ChromePackageFromPackageEntry(iter.Key(), iter.UserData(), &chromePackage,
- mSelectedLocale, mSelectedSkin);
- packages.AppendElement(chromePackage);
- }
- // If we were passed a parent then a new child process has been created and
- // has requested all of the chrome so send it the resources too. Otherwise
- // resource mappings are sent by the resource protocol handler dynamically.
- if (aParent) {
- nsCOMPtr<nsIIOService> io (do_GetIOService());
- NS_ENSURE_TRUE_VOID(io);
- nsCOMPtr<nsIProtocolHandler> ph;
- nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
- NS_ENSURE_SUCCESS_VOID(rv);
- nsCOMPtr<nsIResProtocolHandler> irph (do_QueryInterface(ph));
- nsResProtocolHandler* rph = static_cast<nsResProtocolHandler*>(irph.get());
- rv = rph->CollectSubstitutions(resources);
- NS_ENSURE_SUCCESS_VOID(rv);
- }
- for (auto iter = mOverrideTable.Iter(); !iter.Done(); iter.Next()) {
- SerializedURI chromeURI, overrideURI;
- SerializeURI(iter.Key(), chromeURI);
- SerializeURI(iter.UserData(), overrideURI);
- OverrideMapping override = { chromeURI, overrideURI };
- overrides.AppendElement(override);
- }
- if (aParent) {
- bool success = aParent->SendRegisterChrome(packages, resources, overrides,
- mSelectedLocale, false);
- NS_ENSURE_TRUE_VOID(success);
- } else {
- nsTArray<ContentParent*> parents;
- ContentParent::GetAll(parents);
- if (!parents.Length())
- return;
- for (uint32_t i = 0; i < parents.Length(); i++) {
- DebugOnly<bool> success =
- parents[i]->SendRegisterChrome(packages, resources, overrides,
- mSelectedLocale, true);
- NS_WARNING_ASSERTION(success,
- "couldn't reset a child's registered chrome");
- }
- }
- }
- /* static */ void
- nsChromeRegistryChrome::ChromePackageFromPackageEntry(const nsACString& aPackageName,
- PackageEntry* aPackage,
- ChromePackage* aChromePackage,
- const nsCString& aSelectedLocale,
- const nsCString& aSelectedSkin)
- {
- SerializeURI(aPackage->baseURI, aChromePackage->contentBaseURI);
- SerializeURI(aPackage->locales.GetBase(aSelectedLocale,
- nsProviderArray::LOCALE),
- aChromePackage->localeBaseURI);
- SerializeURI(aPackage->skins.GetBase(aSelectedSkin, nsProviderArray::ANY),
- aChromePackage->skinBaseURI);
- aChromePackage->package = aPackageName;
- aChromePackage->flags = aPackage->flags;
- }
- static bool
- CanLoadResource(nsIURI* aResourceURI)
- {
- bool isLocalResource = false;
- (void)NS_URIChainHasFlags(aResourceURI,
- nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
- &isLocalResource);
- return isLocalResource;
- }
- nsIURI*
- nsChromeRegistryChrome::GetBaseURIFromPackage(const nsCString& aPackage,
- const nsCString& aProvider,
- const nsCString& aPath)
- {
- PackageEntry* entry;
- if (!mPackagesHash.Get(aPackage, &entry)) {
- if (!mInitialized)
- return nullptr;
- LogMessage("No chrome package registered for chrome://%s/%s/%s",
- aPackage.get(), aProvider.get(), aPath.get());
- return nullptr;
- }
- if (aProvider.EqualsLiteral("locale")) {
- return entry->locales.GetBase(mSelectedLocale, nsProviderArray::LOCALE);
- }
- else if (aProvider.EqualsLiteral("skin")) {
- return entry->skins.GetBase(mSelectedSkin, nsProviderArray::ANY);
- }
- else if (aProvider.EqualsLiteral("content")) {
- return entry->baseURI;
- }
- return nullptr;
- }
- nsresult
- nsChromeRegistryChrome::GetFlagsFromPackage(const nsCString& aPackage,
- uint32_t* aFlags)
- {
- PackageEntry* entry;
- if (!mPackagesHash.Get(aPackage, &entry))
- return NS_ERROR_FILE_NOT_FOUND;
- *aFlags = entry->flags;
- return NS_OK;
- }
- nsChromeRegistryChrome::ProviderEntry*
- nsChromeRegistryChrome::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
- {
- size_t i = mArray.Length();
- if (!i)
- return nullptr;
- ProviderEntry* found = nullptr; // Only set if we find a partial-match locale
- ProviderEntry* entry = nullptr;
- while (i--) {
- entry = &mArray[i];
- if (aPreferred.Equals(entry->provider))
- return entry;
- if (aType != LOCALE)
- continue;
- if (LanguagesMatch(aPreferred, entry->provider)) {
- found = entry;
- continue;
- }
- if (!found && entry->provider.EqualsLiteral("en-US"))
- found = entry;
- }
- if (!found && aType != EXACT)
- return entry;
- return found;
- }
- nsIURI*
- nsChromeRegistryChrome::nsProviderArray::GetBase(const nsACString& aPreferred, MatchType aType)
- {
- ProviderEntry* provider = GetProvider(aPreferred, aType);
- if (!provider)
- return nullptr;
- return provider->baseURI;
- }
- const nsACString&
- nsChromeRegistryChrome::nsProviderArray::GetSelected(const nsACString& aPreferred, MatchType aType)
- {
- ProviderEntry* entry = GetProvider(aPreferred, aType);
- if (entry)
- return entry->provider;
- return EmptyCString();
- }
- void
- nsChromeRegistryChrome::nsProviderArray::SetBase(const nsACString& aProvider, nsIURI* aBaseURL)
- {
- ProviderEntry* provider = GetProvider(aProvider, EXACT);
- if (provider) {
- provider->baseURI = aBaseURL;
- return;
- }
- // no existing entries, add a new one
- mArray.AppendElement(ProviderEntry(aProvider, aBaseURL));
- }
- void
- nsChromeRegistryChrome::nsProviderArray::EnumerateToArray(nsTArray<nsCString> *a)
- {
- int32_t i = mArray.Length();
- while (i--) {
- a->AppendElement(mArray[i].provider);
- }
- }
- void
- nsChromeRegistryChrome::OverlayListEntry::AddURI(nsIURI* aURI)
- {
- int32_t i = mArray.Count();
- while (i--) {
- bool equals;
- if (NS_SUCCEEDED(aURI->Equals(mArray[i], &equals)) && equals)
- return;
- }
- mArray.AppendObject(aURI);
- }
- void
- nsChromeRegistryChrome::OverlayListHash::Add(nsIURI* aBase, nsIURI* aOverlay)
- {
- OverlayListEntry* entry = mTable.PutEntry(aBase);
- if (entry)
- entry->AddURI(aOverlay);
- }
- const nsCOMArray<nsIURI>*
- nsChromeRegistryChrome::OverlayListHash::GetArray(nsIURI* aBase)
- {
- OverlayListEntry* entry = mTable.GetEntry(aBase);
- if (!entry)
- return nullptr;
- return &entry->mArray;
- }
- #ifdef MOZ_XUL
- NS_IMETHODIMP
- nsChromeRegistryChrome::GetStyleOverlays(nsIURI *aChromeURL,
- nsISimpleEnumerator **aResult)
- {
- nsCOMPtr<nsIURI> chromeURLWithoutHash;
- if (aChromeURL) {
- aChromeURL->CloneIgnoringRef(getter_AddRefs(chromeURLWithoutHash));
- }
- const nsCOMArray<nsIURI>* parray = mStyleHash.GetArray(chromeURLWithoutHash);
- if (!parray)
- return NS_NewEmptyEnumerator(aResult);
- return NS_NewArrayEnumerator(aResult, *parray);
- }
- NS_IMETHODIMP
- nsChromeRegistryChrome::GetXULOverlays(nsIURI *aChromeURL,
- nsISimpleEnumerator **aResult)
- {
- nsCOMPtr<nsIURI> chromeURLWithoutHash;
- if (aChromeURL) {
- aChromeURL->CloneIgnoringRef(getter_AddRefs(chromeURLWithoutHash));
- }
- const nsCOMArray<nsIURI>* parray = mOverlayHash.GetArray(chromeURLWithoutHash);
- if (!parray)
- return NS_NewEmptyEnumerator(aResult);
- return NS_NewArrayEnumerator(aResult, *parray);
- }
- #endif // MOZ_XUL
- nsIURI*
- nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
- {
- if (!mManifestURI) {
- nsCString uri;
- mFile.GetURIString(uri);
- NS_NewURI(getter_AddRefs(mManifestURI), uri);
- }
- return mManifestURI;
- }
- nsIXPConnect*
- nsChromeRegistry::ManifestProcessingContext::GetXPConnect()
- {
- if (!mXPConnect)
- mXPConnect = do_GetService("@mozilla.org/js/xpc/XPConnect;1");
- return mXPConnect;
- }
- already_AddRefed<nsIURI>
- nsChromeRegistry::ManifestProcessingContext::ResolveURI(const char* uri)
- {
- nsIURI* baseuri = GetManifestURI();
- if (!baseuri)
- return nullptr;
- nsCOMPtr<nsIURI> resolved;
- nsresult rv = NS_NewURI(getter_AddRefs(resolved), uri, baseuri);
- if (NS_FAILED(rv))
- return nullptr;
- return resolved.forget();
- }
- static void
- EnsureLowerCase(char *aBuf)
- {
- for (; *aBuf; ++aBuf) {
- char ch = *aBuf;
- if (ch >= 'A' && ch <= 'Z')
- *aBuf = ch + 'a' - 'A';
- }
- }
- static void
- SendManifestEntry(const ChromeRegistryItem &aItem)
- {
- nsTArray<ContentParent*> parents;
- ContentParent::GetAll(parents);
- if (!parents.Length())
- return;
- for (uint32_t i = 0; i < parents.Length(); i++) {
- Unused << parents[i]->SendRegisterChromeItem(aItem);
- }
- }
- void
- nsChromeRegistryChrome::ManifestContent(ManifestProcessingContext& cx, int lineno,
- char *const * argv, int flags)
- {
- char* package = argv[0];
- char* uri = argv[1];
- EnsureLowerCase(package);
- nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
- if (!resolved) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "During chrome registration, unable to create URI '%s'.", uri);
- return;
- }
- if (!CanLoadResource(resolved)) {
- LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
- "During chrome registration, cannot register non-local URI '%s' as content.",
- uri);
- return;
- }
- nsDependentCString packageName(package);
- PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
- entry->baseURI = resolved;
- entry->flags = flags;
- if (mDynamicRegistration) {
- ChromePackage chromePackage;
- ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
- mSelectedLocale, mSelectedSkin);
- SendManifestEntry(chromePackage);
- }
- }
- void
- nsChromeRegistryChrome::ManifestLocale(ManifestProcessingContext& cx, int lineno,
- char *const * argv, int flags)
- {
- char* package = argv[0];
- char* provider = argv[1];
- char* uri = argv[2];
- EnsureLowerCase(package);
- nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
- if (!resolved) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "During chrome registration, unable to create URI '%s'.", uri);
- return;
- }
- if (!CanLoadResource(resolved)) {
- LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
- "During chrome registration, cannot register non-local URI '%s' as content.",
- uri);
- return;
- }
- nsDependentCString packageName(package);
- PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
- entry->locales.SetBase(nsDependentCString(provider), resolved);
- if (mDynamicRegistration) {
- ChromePackage chromePackage;
- ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
- mSelectedLocale, mSelectedSkin);
- SendManifestEntry(chromePackage);
- }
- }
- void
- nsChromeRegistryChrome::ManifestSkin(ManifestProcessingContext& cx, int lineno,
- char *const * argv, int flags)
- {
- char* package = argv[0];
- char* provider = argv[1];
- char* uri = argv[2];
- EnsureLowerCase(package);
- nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
- if (!resolved) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "During chrome registration, unable to create URI '%s'.", uri);
- return;
- }
- if (!CanLoadResource(resolved)) {
- LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
- "During chrome registration, cannot register non-local URI '%s' as content.",
- uri);
- return;
- }
- nsDependentCString packageName(package);
- PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
- entry->skins.SetBase(nsDependentCString(provider), resolved);
- if (mDynamicRegistration) {
- ChromePackage chromePackage;
- ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
- mSelectedLocale, mSelectedSkin);
- SendManifestEntry(chromePackage);
- }
- }
- void
- nsChromeRegistryChrome::ManifestOverlay(ManifestProcessingContext& cx, int lineno,
- char *const * argv, int flags)
- {
- char* base = argv[0];
- char* overlay = argv[1];
- nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
- nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
- if (!baseuri || !overlayuri) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "During chrome registration, unable to create URI.");
- return;
- }
- if (!CanLoadResource(overlayuri)) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "Cannot register non-local URI '%s' as an overlay.", overlay);
- return;
- }
- nsCOMPtr<nsIURI> baseuriWithoutHash;
- baseuri->CloneIgnoringRef(getter_AddRefs(baseuriWithoutHash));
- mOverlayHash.Add(baseuriWithoutHash, overlayuri);
- }
- void
- nsChromeRegistryChrome::ManifestStyle(ManifestProcessingContext& cx, int lineno,
- char *const * argv, int flags)
- {
- char* base = argv[0];
- char* overlay = argv[1];
- nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
- nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
- if (!baseuri || !overlayuri) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "During chrome registration, unable to create URI.");
- return;
- }
- if (!CanLoadResource(overlayuri)) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "Cannot register non-local URI '%s' as a style overlay.", overlay);
- return;
- }
- nsCOMPtr<nsIURI> baseuriWithoutHash;
- baseuri->CloneIgnoringRef(getter_AddRefs(baseuriWithoutHash));
- mStyleHash.Add(baseuriWithoutHash, overlayuri);
- }
- void
- nsChromeRegistryChrome::ManifestOverride(ManifestProcessingContext& cx, int lineno,
- char *const * argv, int flags)
- {
- char* chrome = argv[0];
- char* resolved = argv[1];
- nsCOMPtr<nsIURI> chromeuri = cx.ResolveURI(chrome);
- nsCOMPtr<nsIURI> resolveduri = cx.ResolveURI(resolved);
- if (!chromeuri || !resolveduri) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "During chrome registration, unable to create URI.");
- return;
- }
- if (cx.mType == NS_SKIN_LOCATION) {
- bool chromeSkinOnly = false;
- nsresult rv = chromeuri->SchemeIs("chrome", &chromeSkinOnly);
- chromeSkinOnly = chromeSkinOnly && NS_SUCCEEDED(rv);
- if (chromeSkinOnly) {
- rv = resolveduri->SchemeIs("chrome", &chromeSkinOnly);
- chromeSkinOnly = chromeSkinOnly && NS_SUCCEEDED(rv);
- }
- if (chromeSkinOnly) {
- nsAutoCString chromePath, resolvedPath;
- chromeuri->GetPath(chromePath);
- resolveduri->GetPath(resolvedPath);
- chromeSkinOnly = StringBeginsWith(chromePath, NS_LITERAL_CSTRING("/skin/")) &&
- StringBeginsWith(resolvedPath, NS_LITERAL_CSTRING("/skin/"));
- }
- if (!chromeSkinOnly) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "Cannot register non-chrome://.../skin/ URIs '%s' and '%s' as overrides and/or to be overridden from a skin manifest.",
- chrome, resolved);
- return;
- }
- }
- if (!CanLoadResource(resolveduri)) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "Cannot register non-local URI '%s' for an override.", resolved);
- return;
- }
- mOverrideTable.Put(chromeuri, resolveduri);
- if (mDynamicRegistration) {
- SerializedURI serializedChrome;
- SerializedURI serializedOverride;
- SerializeURI(chromeuri, serializedChrome);
- SerializeURI(resolveduri, serializedOverride);
- OverrideMapping override = { serializedChrome, serializedOverride };
- SendManifestEntry(override);
- }
- }
- void
- nsChromeRegistryChrome::ManifestResource(ManifestProcessingContext& cx, int lineno,
- char *const * argv, int flags)
- {
- char* package = argv[0];
- char* uri = argv[1];
- EnsureLowerCase(package);
- nsDependentCString host(package);
- nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
- if (!io) {
- NS_WARNING("No IO service trying to process chrome manifests");
- return;
- }
- nsCOMPtr<nsIProtocolHandler> ph;
- nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
- if (NS_FAILED(rv))
- return;
- nsCOMPtr<nsIResProtocolHandler> rph = do_QueryInterface(ph);
- nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
- if (!resolved) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "During chrome registration, unable to create URI '%s'.", uri);
- return;
- }
- if (!CanLoadResource(resolved)) {
- LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
- "Warning: cannot register non-local URI '%s' as a resource.",
- uri);
- return;
- }
- rph->SetSubstitution(host, resolved);
- }
|