Bug 1527483 [wpt PR 15346] - Update wpt metadata, a=testonly
[gecko.git] / chrome / nsChromeRegistryChrome.cpp
blobea71f8f6acdde71813bd374355bf7df230258aa8
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sts=2 sw=2 et tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/ContentParent.h"
8 #include "RegistryMessageUtils.h"
9 #include "nsResProtocolHandler.h"
11 #include "nsChromeRegistryChrome.h"
13 #if defined(XP_WIN)
14 # include <windows.h>
15 #elif defined(XP_MACOSX)
16 # include <CoreServices/CoreServices.h>
17 #endif
19 #include "nsArrayEnumerator.h"
20 #include "nsComponentManager.h"
21 #include "nsEnumeratorUtils.h"
22 #include "nsNetUtil.h"
23 #include "nsStringEnumerator.h"
24 #include "nsTextFormatter.h"
25 #include "nsXPCOMCIDInternal.h"
27 #include "mozilla/LookAndFeel.h"
28 #include "mozilla/Unused.h"
29 #include "mozilla/intl/LocaleService.h"
31 #include "nsIObserverService.h"
32 #include "nsIPrefBranch.h"
33 #include "nsIPrefService.h"
34 #include "mozilla/Preferences.h"
35 #include "nsIResProtocolHandler.h"
36 #include "nsIScriptError.h"
37 #include "nsIXULRuntime.h"
39 #define SELECTED_SKIN_PREF "general.skins.selectedSkin"
40 #define PACKAGE_OVERRIDE_BRANCH "chrome.override_package."
42 using namespace mozilla;
43 using mozilla::dom::ContentParent;
44 using mozilla::dom::PContentParent;
45 using mozilla::intl::LocaleService;
47 // We use a "best-fit" algorithm for matching locales and themes.
48 // 1) the exact selected locale/theme
49 // 2) (locales only) same language, different country
50 // e.g. en-GB is the selected locale, only en-US is available
51 // 3) any available locale/theme
53 /**
54 * Match the language-part of two lang-COUNTRY codes, hopefully but
55 * not guaranteed to be in the form ab-CD or abz-CD. "ab" should also
56 * work, any other garbage-in will produce undefined results as long
57 * as it does not crash.
59 static bool LanguagesMatch(const nsACString& a, const nsACString& b) {
60 if (a.Length() < 2 || b.Length() < 2) return false;
62 nsACString::const_iterator as, ae, bs, be;
63 a.BeginReading(as);
64 a.EndReading(ae);
65 b.BeginReading(bs);
66 b.EndReading(be);
68 while (*as == *bs) {
69 if (*as == '-') return true;
71 ++as;
72 ++bs;
74 // reached the end
75 if (as == ae && bs == be) return true;
77 // "a" is short
78 if (as == ae) return (*bs == '-');
80 // "b" is short
81 if (bs == be) return (*as == '-');
84 return false;
87 nsChromeRegistryChrome::nsChromeRegistryChrome()
88 : mProfileLoaded(false), mDynamicRegistration(true) {}
90 nsChromeRegistryChrome::~nsChromeRegistryChrome() {}
92 nsresult nsChromeRegistryChrome::Init() {
93 nsresult rv = nsChromeRegistry::Init();
94 if (NS_FAILED(rv)) return rv;
96 mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0");
98 bool safeMode = false;
99 nsCOMPtr<nsIXULRuntime> xulrun(do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
100 if (xulrun) xulrun->GetInSafeMode(&safeMode);
102 nsCOMPtr<nsIPrefService> prefserv(do_GetService(NS_PREFSERVICE_CONTRACTID));
103 nsCOMPtr<nsIPrefBranch> prefs;
105 if (prefserv) {
106 if (safeMode) {
107 prefserv->GetDefaultBranch(nullptr, getter_AddRefs(prefs));
108 } else {
109 prefs = do_QueryInterface(prefserv);
113 if (!prefs) {
114 NS_WARNING("Could not get pref service!");
115 } else {
116 nsAutoCString provider;
117 rv = prefs->GetCharPref(SELECTED_SKIN_PREF, provider);
118 if (NS_SUCCEEDED(rv)) mSelectedSkin = provider;
120 rv = prefs->AddObserver(SELECTED_SKIN_PREF, this, true);
123 nsCOMPtr<nsIObserverService> obsService =
124 mozilla::services::GetObserverService();
125 if (obsService) {
126 obsService->AddObserver(this, "profile-initial-state", true);
127 obsService->AddObserver(this, "intl:app-locales-changed", true);
130 return NS_OK;
133 NS_IMETHODIMP
134 nsChromeRegistryChrome::CheckForOSAccessibility() {
135 int32_t useAccessibilityTheme =
136 LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme, 0);
138 if (useAccessibilityTheme) {
139 /* Set the skin to classic and remove pref observers */
140 if (!mSelectedSkin.EqualsLiteral("classic/1.0")) {
141 mSelectedSkin.AssignLiteral("classic/1.0");
142 RefreshSkins();
145 nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
146 if (prefs) {
147 prefs->RemoveObserver(SELECTED_SKIN_PREF, this);
151 return NS_OK;
154 NS_IMETHODIMP
155 nsChromeRegistryChrome::GetLocalesForPackage(
156 const nsACString& aPackage, nsIUTF8StringEnumerator** aResult) {
157 nsCString realpackage;
158 nsresult rv = OverrideLocalePackage(aPackage, realpackage);
159 if (NS_FAILED(rv)) return rv;
161 nsTArray<nsCString>* a = new nsTArray<nsCString>;
162 if (!a) return NS_ERROR_OUT_OF_MEMORY;
164 PackageEntry* entry;
165 if (mPackagesHash.Get(realpackage, &entry)) {
166 entry->locales.EnumerateToArray(a);
169 rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a);
170 if (NS_FAILED(rv)) delete a;
172 return rv;
175 NS_IMETHODIMP
176 nsChromeRegistryChrome::IsLocaleRTL(const nsACString& package, bool* aResult) {
177 *aResult = false;
179 nsAutoCString locale;
180 GetSelectedLocale(package, false, locale);
181 if (locale.Length() < 2) return NS_OK;
183 *aResult = GetDirectionForLocale(locale);
184 return NS_OK;
188 * This method negotiates only between the app locale and the available
189 * chrome packages.
191 * If you want to get the current application's UI locale, please use
192 * LocaleService::GetAppLocaleAsLangTag.
194 nsresult nsChromeRegistryChrome::GetSelectedLocale(const nsACString& aPackage,
195 bool aAsBCP47,
196 nsACString& aLocale) {
197 nsAutoCString reqLocale;
198 if (aPackage.EqualsLiteral("global")) {
199 LocaleService::GetInstance()->GetAppLocaleAsLangTag(reqLocale);
200 } else {
201 AutoTArray<nsCString, 10> requestedLocales;
202 LocaleService::GetInstance()->GetRequestedLocales(requestedLocales);
203 reqLocale.Assign(requestedLocales[0]);
206 nsCString realpackage;
207 nsresult rv = OverrideLocalePackage(aPackage, realpackage);
208 if (NS_FAILED(rv)) return rv;
209 PackageEntry* entry;
210 if (!mPackagesHash.Get(realpackage, &entry)) return NS_ERROR_FILE_NOT_FOUND;
212 aLocale = entry->locales.GetSelected(reqLocale, nsProviderArray::LOCALE);
213 if (aLocale.IsEmpty()) return NS_ERROR_FAILURE;
215 if (aAsBCP47) {
216 SanitizeForBCP47(aLocale);
219 return NS_OK;
222 nsresult nsChromeRegistryChrome::OverrideLocalePackage(
223 const nsACString& aPackage, nsACString& aOverride) {
224 const nsACString& pref =
225 NS_LITERAL_CSTRING(PACKAGE_OVERRIDE_BRANCH) + aPackage;
226 nsAutoCString override;
227 nsresult rv = mozilla::Preferences::GetCString(PromiseFlatCString(pref).get(),
228 override);
229 if (NS_SUCCEEDED(rv)) {
230 aOverride = override;
231 } else {
232 aOverride = aPackage;
234 return NS_OK;
237 NS_IMETHODIMP
238 nsChromeRegistryChrome::Observe(nsISupports* aSubject, const char* aTopic,
239 const char16_t* someData) {
240 nsresult rv = NS_OK;
242 if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
243 nsCOMPtr<nsIPrefBranch> prefs(do_QueryInterface(aSubject));
244 NS_ASSERTION(prefs, "Bad observer call!");
246 NS_ConvertUTF16toUTF8 pref(someData);
248 if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
249 nsAutoCString provider;
250 rv = prefs->GetCharPref(pref.get(), provider);
251 if (NS_FAILED(rv)) {
252 NS_ERROR("Couldn't get new skin pref!");
253 return rv;
256 mSelectedSkin = provider;
257 RefreshSkins();
258 } else {
259 NS_ERROR("Unexpected pref!");
261 } else if (!strcmp("profile-initial-state", aTopic)) {
262 mProfileLoaded = true;
263 } else if (!strcmp("intl:app-locales-changed", aTopic)) {
264 if (mProfileLoaded) {
265 FlushAllCaches();
267 } else {
268 NS_ERROR("Unexpected observer topic!");
271 return rv;
274 NS_IMETHODIMP
275 nsChromeRegistryChrome::CheckForNewChrome() {
276 mPackagesHash.Clear();
277 mOverrideTable.Clear();
279 mDynamicRegistration = false;
281 nsComponentManagerImpl::gComponentManager->RereadChromeManifests();
283 mDynamicRegistration = true;
285 SendRegisteredChrome(nullptr);
286 return NS_OK;
289 static void SerializeURI(nsIURI* aURI, SerializedURI& aSerializedURI) {
290 if (!aURI) return;
292 aURI->GetSpec(aSerializedURI.spec);
295 void nsChromeRegistryChrome::SendRegisteredChrome(
296 mozilla::dom::PContentParent* aParent) {
297 InfallibleTArray<ChromePackage> packages;
298 InfallibleTArray<SubstitutionMapping> resources;
299 InfallibleTArray<OverrideMapping> overrides;
301 for (auto iter = mPackagesHash.Iter(); !iter.Done(); iter.Next()) {
302 ChromePackage chromePackage;
303 ChromePackageFromPackageEntry(iter.Key(), iter.UserData(), &chromePackage,
304 mSelectedSkin);
305 packages.AppendElement(chromePackage);
308 // If we were passed a parent then a new child process has been created and
309 // has requested all of the chrome so send it the resources too. Otherwise
310 // resource mappings are sent by the resource protocol handler dynamically.
311 if (aParent) {
312 nsCOMPtr<nsIIOService> io(do_GetIOService());
313 NS_ENSURE_TRUE_VOID(io);
315 nsCOMPtr<nsIProtocolHandler> ph;
316 nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
317 NS_ENSURE_SUCCESS_VOID(rv);
319 nsCOMPtr<nsIResProtocolHandler> irph(do_QueryInterface(ph));
320 nsResProtocolHandler* rph = static_cast<nsResProtocolHandler*>(irph.get());
321 rv = rph->CollectSubstitutions(resources);
322 NS_ENSURE_SUCCESS_VOID(rv);
325 for (auto iter = mOverrideTable.Iter(); !iter.Done(); iter.Next()) {
326 SerializedURI chromeURI, overrideURI;
328 SerializeURI(iter.Key(), chromeURI);
329 SerializeURI(iter.UserData(), overrideURI);
331 OverrideMapping override = {chromeURI, overrideURI};
332 overrides.AppendElement(override);
335 nsAutoCString appLocale;
336 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
338 if (aParent) {
339 bool success = aParent->SendRegisterChrome(packages, resources, overrides,
340 appLocale, false);
341 NS_ENSURE_TRUE_VOID(success);
342 } else {
343 nsTArray<ContentParent*> parents;
344 ContentParent::GetAll(parents);
345 if (!parents.Length()) return;
347 for (uint32_t i = 0; i < parents.Length(); i++) {
348 DebugOnly<bool> success = parents[i]->SendRegisterChrome(
349 packages, resources, overrides, appLocale, true);
350 NS_WARNING_ASSERTION(success,
351 "couldn't reset a child's registered chrome");
356 /* static */
357 void nsChromeRegistryChrome::ChromePackageFromPackageEntry(
358 const nsACString& aPackageName, PackageEntry* aPackage,
359 ChromePackage* aChromePackage, const nsCString& aSelectedSkin) {
360 nsAutoCString appLocale;
361 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
363 SerializeURI(aPackage->baseURI, aChromePackage->contentBaseURI);
364 SerializeURI(aPackage->locales.GetBase(appLocale, nsProviderArray::LOCALE),
365 aChromePackage->localeBaseURI);
366 SerializeURI(aPackage->skins.GetBase(aSelectedSkin, nsProviderArray::ANY),
367 aChromePackage->skinBaseURI);
368 aChromePackage->package = aPackageName;
369 aChromePackage->flags = aPackage->flags;
372 static bool CanLoadResource(nsIURI* aResourceURI) {
373 bool isLocalResource = false;
374 (void)NS_URIChainHasFlags(aResourceURI,
375 nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
376 &isLocalResource);
377 return isLocalResource;
380 nsIURI* nsChromeRegistryChrome::GetBaseURIFromPackage(
381 const nsCString& aPackage, const nsCString& aProvider,
382 const nsCString& aPath) {
383 PackageEntry* entry;
384 if (!mPackagesHash.Get(aPackage, &entry)) {
385 if (!mInitialized) return nullptr;
387 LogMessage("No chrome package registered for chrome://%s/%s/%s",
388 aPackage.get(), aProvider.get(), aPath.get());
390 return nullptr;
393 if (aProvider.EqualsLiteral("locale")) {
394 nsAutoCString appLocale;
395 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
396 return entry->locales.GetBase(appLocale, nsProviderArray::LOCALE);
397 } else if (aProvider.EqualsLiteral("skin")) {
398 return entry->skins.GetBase(mSelectedSkin, nsProviderArray::ANY);
399 } else if (aProvider.EqualsLiteral("content")) {
400 return entry->baseURI;
402 return nullptr;
405 nsresult nsChromeRegistryChrome::GetFlagsFromPackage(const nsCString& aPackage,
406 uint32_t* aFlags) {
407 PackageEntry* entry;
408 if (!mPackagesHash.Get(aPackage, &entry)) return NS_ERROR_FILE_NOT_FOUND;
410 *aFlags = entry->flags;
411 return NS_OK;
414 nsChromeRegistryChrome::ProviderEntry*
415 nsChromeRegistryChrome::nsProviderArray::GetProvider(
416 const nsACString& aPreferred, MatchType aType) {
417 size_t i = mArray.Length();
418 if (!i) return nullptr;
420 ProviderEntry* found = nullptr; // Only set if we find a partial-match locale
421 ProviderEntry* entry = nullptr;
423 while (i--) {
424 entry = &mArray[i];
425 if (aPreferred.Equals(entry->provider)) return entry;
427 if (aType != LOCALE) continue;
429 if (LanguagesMatch(aPreferred, entry->provider)) {
430 found = entry;
431 continue;
434 if (!found && entry->provider.EqualsLiteral("en-US")) found = entry;
437 if (!found && aType != EXACT) return entry;
439 return found;
442 nsIURI* nsChromeRegistryChrome::nsProviderArray::GetBase(
443 const nsACString& aPreferred, MatchType aType) {
444 ProviderEntry* provider = GetProvider(aPreferred, aType);
446 if (!provider) return nullptr;
448 return provider->baseURI;
451 const nsACString& nsChromeRegistryChrome::nsProviderArray::GetSelected(
452 const nsACString& aPreferred, MatchType aType) {
453 ProviderEntry* entry = GetProvider(aPreferred, aType);
455 if (entry) return entry->provider;
457 return EmptyCString();
460 void nsChromeRegistryChrome::nsProviderArray::SetBase(
461 const nsACString& aProvider, nsIURI* aBaseURL) {
462 ProviderEntry* provider = GetProvider(aProvider, EXACT);
464 if (provider) {
465 provider->baseURI = aBaseURL;
466 return;
469 // no existing entries, add a new one
470 mArray.AppendElement(ProviderEntry(aProvider, aBaseURL));
473 void nsChromeRegistryChrome::nsProviderArray::EnumerateToArray(
474 nsTArray<nsCString>* a) {
475 int32_t i = mArray.Length();
476 while (i--) {
477 a->AppendElement(mArray[i].provider);
481 nsIURI* nsChromeRegistry::ManifestProcessingContext::GetManifestURI() {
482 if (!mManifestURI) {
483 nsCString uri;
484 mFile.GetURIString(uri);
485 NS_NewURI(getter_AddRefs(mManifestURI), uri);
487 return mManifestURI;
490 already_AddRefed<nsIURI>
491 nsChromeRegistry::ManifestProcessingContext::ResolveURI(const char* uri) {
492 nsIURI* baseuri = GetManifestURI();
493 if (!baseuri) return nullptr;
495 nsCOMPtr<nsIURI> resolved;
496 nsresult rv = NS_NewURI(getter_AddRefs(resolved), uri, baseuri);
497 if (NS_FAILED(rv)) return nullptr;
499 return resolved.forget();
502 static void EnsureLowerCase(char* aBuf) {
503 for (; *aBuf; ++aBuf) {
504 char ch = *aBuf;
505 if (ch >= 'A' && ch <= 'Z') *aBuf = ch + 'a' - 'A';
509 static void SendManifestEntry(const ChromeRegistryItem& aItem) {
510 nsTArray<ContentParent*> parents;
511 ContentParent::GetAll(parents);
512 if (!parents.Length()) return;
514 for (uint32_t i = 0; i < parents.Length(); i++) {
515 Unused << parents[i]->SendRegisterChromeItem(aItem);
519 void nsChromeRegistryChrome::ManifestContent(ManifestProcessingContext& cx,
520 int lineno, char* const* argv,
521 int flags) {
522 char* package = argv[0];
523 char* uri = argv[1];
525 EnsureLowerCase(package);
527 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
528 if (!resolved) {
529 LogMessageWithContext(
530 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
531 "During chrome registration, unable to create URI '%s'.", uri);
532 return;
535 if (!CanLoadResource(resolved)) {
536 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
537 "During chrome registration, cannot register "
538 "non-local URI '%s' as content.",
539 uri);
540 return;
543 nsDependentCString packageName(package);
544 PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
545 entry->baseURI = resolved;
546 entry->flags = flags;
548 if (mDynamicRegistration) {
549 ChromePackage chromePackage;
550 ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
551 mSelectedSkin);
552 SendManifestEntry(chromePackage);
556 void nsChromeRegistryChrome::ManifestLocale(ManifestProcessingContext& cx,
557 int lineno, char* const* argv,
558 int flags) {
559 char* package = argv[0];
560 char* provider = argv[1];
561 char* uri = argv[2];
563 EnsureLowerCase(package);
565 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
566 if (!resolved) {
567 LogMessageWithContext(
568 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
569 "During chrome registration, unable to create URI '%s'.", uri);
570 return;
573 if (!CanLoadResource(resolved)) {
574 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
575 "During chrome registration, cannot register "
576 "non-local URI '%s' as content.",
577 uri);
578 return;
581 nsDependentCString packageName(package);
582 PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
583 entry->locales.SetBase(nsDependentCString(provider), resolved);
585 if (mDynamicRegistration) {
586 ChromePackage chromePackage;
587 ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
588 mSelectedSkin);
589 SendManifestEntry(chromePackage);
592 // We use mainPackage as the package we track for reporting new locales being
593 // registered. For most cases it will be "global", but for Fennec it will be
594 // "browser".
595 nsAutoCString mainPackage;
596 nsresult rv =
597 OverrideLocalePackage(NS_LITERAL_CSTRING("global"), mainPackage);
598 if (NS_FAILED(rv)) {
599 return;
603 void nsChromeRegistryChrome::ManifestSkin(ManifestProcessingContext& cx,
604 int lineno, char* const* argv,
605 int flags) {
606 char* package = argv[0];
607 char* provider = argv[1];
608 char* uri = argv[2];
610 EnsureLowerCase(package);
612 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
613 if (!resolved) {
614 LogMessageWithContext(
615 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
616 "During chrome registration, unable to create URI '%s'.", uri);
617 return;
620 if (!CanLoadResource(resolved)) {
621 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
622 "During chrome registration, cannot register "
623 "non-local URI '%s' as content.",
624 uri);
625 return;
628 nsDependentCString packageName(package);
629 PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
630 entry->skins.SetBase(nsDependentCString(provider), resolved);
632 if (mDynamicRegistration) {
633 ChromePackage chromePackage;
634 ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
635 mSelectedSkin);
636 SendManifestEntry(chromePackage);
640 void nsChromeRegistryChrome::ManifestOverride(ManifestProcessingContext& cx,
641 int lineno, char* const* argv,
642 int flags) {
643 char* chrome = argv[0];
644 char* resolved = argv[1];
646 nsCOMPtr<nsIURI> chromeuri = cx.ResolveURI(chrome);
647 nsCOMPtr<nsIURI> resolveduri = cx.ResolveURI(resolved);
648 if (!chromeuri || !resolveduri) {
649 LogMessageWithContext(cx.GetManifestURI(), lineno,
650 nsIScriptError::warningFlag,
651 "During chrome registration, unable to create URI.");
652 return;
655 if (cx.mType == NS_SKIN_LOCATION) {
656 bool chromeSkinOnly = false;
657 nsresult rv = chromeuri->SchemeIs("chrome", &chromeSkinOnly);
658 chromeSkinOnly = chromeSkinOnly && NS_SUCCEEDED(rv);
659 if (chromeSkinOnly) {
660 rv = resolveduri->SchemeIs("chrome", &chromeSkinOnly);
661 chromeSkinOnly = chromeSkinOnly && NS_SUCCEEDED(rv);
663 if (chromeSkinOnly) {
664 nsAutoCString chromePath, resolvedPath;
665 chromeuri->GetPathQueryRef(chromePath);
666 resolveduri->GetPathQueryRef(resolvedPath);
667 chromeSkinOnly =
668 StringBeginsWith(chromePath, NS_LITERAL_CSTRING("/skin/")) &&
669 StringBeginsWith(resolvedPath, NS_LITERAL_CSTRING("/skin/"));
671 if (!chromeSkinOnly) {
672 LogMessageWithContext(
673 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
674 "Cannot register non-chrome://.../skin/ URIs '%s' and '%s' as "
675 "overrides and/or to be overridden from a skin manifest.",
676 chrome, resolved);
677 return;
681 if (!CanLoadResource(resolveduri)) {
682 LogMessageWithContext(
683 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
684 "Cannot register non-local URI '%s' for an override.", resolved);
685 return;
687 mOverrideTable.Put(chromeuri, resolveduri);
689 if (mDynamicRegistration) {
690 SerializedURI serializedChrome;
691 SerializedURI serializedOverride;
693 SerializeURI(chromeuri, serializedChrome);
694 SerializeURI(resolveduri, serializedOverride);
696 OverrideMapping override = {serializedChrome, serializedOverride};
697 SendManifestEntry(override);
701 void nsChromeRegistryChrome::ManifestResource(ManifestProcessingContext& cx,
702 int lineno, char* const* argv,
703 int flags) {
704 char* package = argv[0];
705 char* uri = argv[1];
707 EnsureLowerCase(package);
708 nsDependentCString host(package);
710 nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
711 if (!io) {
712 NS_WARNING("No IO service trying to process chrome manifests");
713 return;
716 nsCOMPtr<nsIProtocolHandler> ph;
717 nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
718 if (NS_FAILED(rv)) return;
720 nsCOMPtr<nsIResProtocolHandler> rph = do_QueryInterface(ph);
722 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
723 if (!resolved) {
724 LogMessageWithContext(
725 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
726 "During chrome registration, unable to create URI '%s'.", uri);
727 return;
730 if (!CanLoadResource(resolved)) {
731 LogMessageWithContext(
732 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
733 "Warning: cannot register non-local URI '%s' as a resource.", uri);
734 return;
737 // By default, Firefox resources are not content-accessible unless the
738 // manifests opts in.
739 bool contentAccessible = (flags & nsChromeRegistry::CONTENT_ACCESSIBLE);
741 uint32_t substitutionFlags = 0;
742 if (contentAccessible) {
743 substitutionFlags |= nsIResProtocolHandler::ALLOW_CONTENT_ACCESS;
745 rv = rph->SetSubstitutionWithFlags(host, resolved, substitutionFlags);
746 if (NS_FAILED(rv)) {
747 LogMessageWithContext(cx.GetManifestURI(), lineno,
748 nsIScriptError::warningFlag,
749 "Warning: cannot set substitution for '%s'.", uri);