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"
15 #elif defined(XP_MACOSX)
16 #include <CoreServices/CoreServices.h>
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
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.
60 LanguagesMatch(const nsACString
& a
, const nsACString
& b
)
62 if (a
.Length() < 2 || b
.Length() < 2)
65 nsACString::const_iterator as
, ae
, bs
, be
;
78 if (as
== ae
&& bs
== be
)
93 nsChromeRegistryChrome::nsChromeRegistryChrome()
94 : mProfileLoaded(false)
95 , mDynamicRegistration(true)
99 nsChromeRegistryChrome::~nsChromeRegistryChrome()
104 nsChromeRegistryChrome::Init()
106 nsresult rv
= nsChromeRegistry::Init();
110 mSelectedSkin
= NS_LITERAL_CSTRING("classic/1.0");
112 bool safeMode
= false;
113 nsCOMPtr
<nsIXULRuntime
> xulrun (do_GetService(XULAPPINFO_SERVICE_CONTRACTID
));
115 xulrun
->GetInSafeMode(&safeMode
);
117 nsCOMPtr
<nsIPrefService
> prefserv (do_GetService(NS_PREFSERVICE_CONTRACTID
));
118 nsCOMPtr
<nsIPrefBranch
> prefs
;
122 prefserv
->GetDefaultBranch(nullptr, getter_AddRefs(prefs
));
124 prefs
= do_QueryInterface(prefserv
);
129 NS_WARNING("Could not get pref service!");
131 nsAutoCString provider
;
132 rv
= prefs
->GetCharPref(SELECTED_SKIN_PREF
, provider
);
133 if (NS_SUCCEEDED(rv
))
134 mSelectedSkin
= provider
;
136 rv
= prefs
->AddObserver(SELECTED_SKIN_PREF
, this, true);
139 nsCOMPtr
<nsIObserverService
> obsService
= mozilla::services::GetObserverService();
141 obsService
->AddObserver(this, "profile-initial-state", true);
142 obsService
->AddObserver(this, "intl:app-locales-changed", true);
149 nsChromeRegistryChrome::CheckForOSAccessibility()
151 int32_t useAccessibilityTheme
=
152 LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme
, 0);
154 if (useAccessibilityTheme
) {
155 /* Set the skin to classic and remove pref observers */
156 if (!mSelectedSkin
.EqualsLiteral("classic/1.0")) {
157 mSelectedSkin
.AssignLiteral("classic/1.0");
161 nsCOMPtr
<nsIPrefBranch
> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID
));
163 prefs
->RemoveObserver(SELECTED_SKIN_PREF
, this);
171 nsChromeRegistryChrome::GetLocalesForPackage(const nsACString
& aPackage
,
172 nsIUTF8StringEnumerator
* *aResult
)
174 nsCString realpackage
;
175 nsresult rv
= OverrideLocalePackage(aPackage
, realpackage
);
179 nsTArray
<nsCString
> *a
= new nsTArray
<nsCString
>;
181 return NS_ERROR_OUT_OF_MEMORY
;
184 if (mPackagesHash
.Get(realpackage
, &entry
)) {
185 entry
->locales
.EnumerateToArray(a
);
188 rv
= NS_NewAdoptingUTF8StringEnumerator(aResult
, a
);
196 nsChromeRegistryChrome::IsLocaleRTL(const nsACString
& package
, bool *aResult
)
200 nsAutoCString locale
;
201 GetSelectedLocale(package
, false, locale
);
202 if (locale
.Length() < 2)
205 *aResult
= GetDirectionForLocale(locale
);
210 * This method negotiates only between the app locale and the available
213 * If you want to get the current application's UI locale, please use
214 * LocaleService::GetAppLocaleAsLangTag.
217 nsChromeRegistryChrome::GetSelectedLocale(const nsACString
& aPackage
,
221 nsAutoCString reqLocale
;
222 if (aPackage
.EqualsLiteral("global")) {
223 LocaleService::GetInstance()->GetAppLocaleAsLangTag(reqLocale
);
225 AutoTArray
<nsCString
, 10> requestedLocales
;
226 LocaleService::GetInstance()->GetRequestedLocales(requestedLocales
);
227 reqLocale
.Assign(requestedLocales
[0]);
230 nsCString realpackage
;
231 nsresult rv
= OverrideLocalePackage(aPackage
, realpackage
);
235 if (!mPackagesHash
.Get(realpackage
, &entry
))
236 return NS_ERROR_FILE_NOT_FOUND
;
238 aLocale
= entry
->locales
.GetSelected(reqLocale
, nsProviderArray::LOCALE
);
239 if (aLocale
.IsEmpty())
240 return NS_ERROR_FAILURE
;
243 SanitizeForBCP47(aLocale
);
250 nsChromeRegistryChrome::OverrideLocalePackage(const nsACString
& aPackage
,
251 nsACString
& aOverride
)
253 const nsACString
& pref
= NS_LITERAL_CSTRING(PACKAGE_OVERRIDE_BRANCH
) + aPackage
;
254 nsAutoCString override
;
256 mozilla::Preferences::GetCString(PromiseFlatCString(pref
).get(), override
);
257 if (NS_SUCCEEDED(rv
)) {
258 aOverride
= override
;
260 aOverride
= aPackage
;
266 nsChromeRegistryChrome::Observe(nsISupports
*aSubject
, const char *aTopic
,
267 const char16_t
*someData
)
271 if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID
, aTopic
)) {
272 nsCOMPtr
<nsIPrefBranch
> prefs (do_QueryInterface(aSubject
));
273 NS_ASSERTION(prefs
, "Bad observer call!");
275 NS_ConvertUTF16toUTF8
pref(someData
);
277 if (pref
.EqualsLiteral(SELECTED_SKIN_PREF
)) {
278 nsAutoCString provider
;
279 rv
= prefs
->GetCharPref(pref
.get(), provider
);
281 NS_ERROR("Couldn't get new skin pref!");
285 mSelectedSkin
= provider
;
288 NS_ERROR("Unexpected pref!");
291 else if (!strcmp("profile-initial-state", aTopic
)) {
292 mProfileLoaded
= true;
294 else if (!strcmp("intl:app-locales-changed", aTopic
)) {
295 if (mProfileLoaded
) {
300 NS_ERROR("Unexpected observer topic!");
307 nsChromeRegistryChrome::CheckForNewChrome()
309 mPackagesHash
.Clear();
310 mOverrideTable
.Clear();
312 mDynamicRegistration
= false;
314 nsComponentManagerImpl::gComponentManager
->RereadChromeManifests();
316 mDynamicRegistration
= true;
318 SendRegisteredChrome(nullptr);
323 SerializeURI(nsIURI
* aURI
,
324 SerializedURI
& aSerializedURI
)
329 aURI
->GetSpec(aSerializedURI
.spec
);
333 nsChromeRegistryChrome::SendRegisteredChrome(
334 mozilla::dom::PContentParent
* aParent
)
336 InfallibleTArray
<ChromePackage
> packages
;
337 InfallibleTArray
<SubstitutionMapping
> resources
;
338 InfallibleTArray
<OverrideMapping
> overrides
;
340 for (auto iter
= mPackagesHash
.Iter(); !iter
.Done(); iter
.Next()) {
341 ChromePackage chromePackage
;
342 ChromePackageFromPackageEntry(iter
.Key(), iter
.UserData(), &chromePackage
,
344 packages
.AppendElement(chromePackage
);
347 // If we were passed a parent then a new child process has been created and
348 // has requested all of the chrome so send it the resources too. Otherwise
349 // resource mappings are sent by the resource protocol handler dynamically.
351 nsCOMPtr
<nsIIOService
> io (do_GetIOService());
352 NS_ENSURE_TRUE_VOID(io
);
354 nsCOMPtr
<nsIProtocolHandler
> ph
;
355 nsresult rv
= io
->GetProtocolHandler("resource", getter_AddRefs(ph
));
356 NS_ENSURE_SUCCESS_VOID(rv
);
358 nsCOMPtr
<nsIResProtocolHandler
> irph (do_QueryInterface(ph
));
359 nsResProtocolHandler
* rph
= static_cast<nsResProtocolHandler
*>(irph
.get());
360 rv
= rph
->CollectSubstitutions(resources
);
361 NS_ENSURE_SUCCESS_VOID(rv
);
364 for (auto iter
= mOverrideTable
.Iter(); !iter
.Done(); iter
.Next()) {
365 SerializedURI chromeURI
, overrideURI
;
367 SerializeURI(iter
.Key(), chromeURI
);
368 SerializeURI(iter
.UserData(), overrideURI
);
370 OverrideMapping override
= { chromeURI
, overrideURI
};
371 overrides
.AppendElement(override
);
374 nsAutoCString appLocale
;
375 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale
);
378 bool success
= aParent
->SendRegisterChrome(packages
, resources
, overrides
,
380 NS_ENSURE_TRUE_VOID(success
);
382 nsTArray
<ContentParent
*> parents
;
383 ContentParent::GetAll(parents
);
384 if (!parents
.Length())
387 for (uint32_t i
= 0; i
< parents
.Length(); i
++) {
388 DebugOnly
<bool> success
=
389 parents
[i
]->SendRegisterChrome(packages
, resources
, overrides
,
391 NS_WARNING_ASSERTION(success
,
392 "couldn't reset a child's registered chrome");
398 nsChromeRegistryChrome::ChromePackageFromPackageEntry(const nsACString
& aPackageName
,
399 PackageEntry
* aPackage
,
400 ChromePackage
* aChromePackage
,
401 const nsCString
& aSelectedSkin
)
403 nsAutoCString appLocale
;
404 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale
);
406 SerializeURI(aPackage
->baseURI
, aChromePackage
->contentBaseURI
);
407 SerializeURI(aPackage
->locales
.GetBase(appLocale
, nsProviderArray::LOCALE
),
408 aChromePackage
->localeBaseURI
);
409 SerializeURI(aPackage
->skins
.GetBase(aSelectedSkin
, nsProviderArray::ANY
),
410 aChromePackage
->skinBaseURI
);
411 aChromePackage
->package
= aPackageName
;
412 aChromePackage
->flags
= aPackage
->flags
;
416 CanLoadResource(nsIURI
* aResourceURI
)
418 bool isLocalResource
= false;
419 (void)NS_URIChainHasFlags(aResourceURI
,
420 nsIProtocolHandler::URI_IS_LOCAL_RESOURCE
,
422 return isLocalResource
;
426 nsChromeRegistryChrome::GetBaseURIFromPackage(const nsCString
& aPackage
,
427 const nsCString
& aProvider
,
428 const nsCString
& aPath
)
431 if (!mPackagesHash
.Get(aPackage
, &entry
)) {
435 LogMessage("No chrome package registered for chrome://%s/%s/%s",
436 aPackage
.get(), aProvider
.get(), aPath
.get());
441 if (aProvider
.EqualsLiteral("locale")) {
442 nsAutoCString appLocale
;
443 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale
);
444 return entry
->locales
.GetBase(appLocale
, nsProviderArray::LOCALE
);
446 else if (aProvider
.EqualsLiteral("skin")) {
447 return entry
->skins
.GetBase(mSelectedSkin
, nsProviderArray::ANY
);
449 else if (aProvider
.EqualsLiteral("content")) {
450 return entry
->baseURI
;
456 nsChromeRegistryChrome::GetFlagsFromPackage(const nsCString
& aPackage
,
460 if (!mPackagesHash
.Get(aPackage
, &entry
))
461 return NS_ERROR_FILE_NOT_FOUND
;
463 *aFlags
= entry
->flags
;
467 nsChromeRegistryChrome::ProviderEntry
*
468 nsChromeRegistryChrome::nsProviderArray::GetProvider(const nsACString
& aPreferred
, MatchType aType
)
470 size_t i
= mArray
.Length();
474 ProviderEntry
* found
= nullptr; // Only set if we find a partial-match locale
475 ProviderEntry
* entry
= nullptr;
479 if (aPreferred
.Equals(entry
->provider
))
485 if (LanguagesMatch(aPreferred
, entry
->provider
)) {
490 if (!found
&& entry
->provider
.EqualsLiteral("en-US"))
494 if (!found
&& aType
!= EXACT
)
501 nsChromeRegistryChrome::nsProviderArray::GetBase(const nsACString
& aPreferred
, MatchType aType
)
503 ProviderEntry
* provider
= GetProvider(aPreferred
, aType
);
508 return provider
->baseURI
;
512 nsChromeRegistryChrome::nsProviderArray::GetSelected(const nsACString
& aPreferred
, MatchType aType
)
514 ProviderEntry
* entry
= GetProvider(aPreferred
, aType
);
517 return entry
->provider
;
519 return EmptyCString();
523 nsChromeRegistryChrome::nsProviderArray::SetBase(const nsACString
& aProvider
, nsIURI
* aBaseURL
)
525 ProviderEntry
* provider
= GetProvider(aProvider
, EXACT
);
528 provider
->baseURI
= aBaseURL
;
532 // no existing entries, add a new one
533 mArray
.AppendElement(ProviderEntry(aProvider
, aBaseURL
));
537 nsChromeRegistryChrome::nsProviderArray::EnumerateToArray(nsTArray
<nsCString
> *a
)
539 int32_t i
= mArray
.Length();
541 a
->AppendElement(mArray
[i
].provider
);
546 nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
550 mFile
.GetURIString(uri
);
551 NS_NewURI(getter_AddRefs(mManifestURI
), uri
);
556 already_AddRefed
<nsIURI
>
557 nsChromeRegistry::ManifestProcessingContext::ResolveURI(const char* uri
)
559 nsIURI
* baseuri
= GetManifestURI();
563 nsCOMPtr
<nsIURI
> resolved
;
564 nsresult rv
= NS_NewURI(getter_AddRefs(resolved
), uri
, baseuri
);
568 return resolved
.forget();
572 EnsureLowerCase(char *aBuf
)
574 for (; *aBuf
; ++aBuf
) {
576 if (ch
>= 'A' && ch
<= 'Z')
577 *aBuf
= ch
+ 'a' - 'A';
582 SendManifestEntry(const ChromeRegistryItem
&aItem
)
584 nsTArray
<ContentParent
*> parents
;
585 ContentParent::GetAll(parents
);
586 if (!parents
.Length())
589 for (uint32_t i
= 0; i
< parents
.Length(); i
++) {
590 Unused
<< parents
[i
]->SendRegisterChromeItem(aItem
);
595 nsChromeRegistryChrome::ManifestContent(ManifestProcessingContext
& cx
, int lineno
,
596 char *const * argv
, int flags
)
598 char* package
= argv
[0];
601 EnsureLowerCase(package
);
603 nsCOMPtr
<nsIURI
> resolved
= cx
.ResolveURI(uri
);
605 LogMessageWithContext(cx
.GetManifestURI(), lineno
, nsIScriptError::warningFlag
,
606 "During chrome registration, unable to create URI '%s'.", uri
);
610 if (!CanLoadResource(resolved
)) {
611 LogMessageWithContext(resolved
, lineno
, nsIScriptError::warningFlag
,
612 "During chrome registration, cannot register non-local URI '%s' as content.",
617 nsDependentCString
packageName(package
);
618 PackageEntry
* entry
= mPackagesHash
.LookupOrAdd(packageName
);
619 entry
->baseURI
= resolved
;
620 entry
->flags
= flags
;
622 if (mDynamicRegistration
) {
623 ChromePackage chromePackage
;
624 ChromePackageFromPackageEntry(packageName
, entry
, &chromePackage
,
626 SendManifestEntry(chromePackage
);
631 nsChromeRegistryChrome::ManifestLocale(ManifestProcessingContext
& cx
, int lineno
,
632 char *const * argv
, int flags
)
634 char* package
= argv
[0];
635 char* provider
= argv
[1];
638 EnsureLowerCase(package
);
640 nsCOMPtr
<nsIURI
> resolved
= cx
.ResolveURI(uri
);
642 LogMessageWithContext(cx
.GetManifestURI(), lineno
, nsIScriptError::warningFlag
,
643 "During chrome registration, unable to create URI '%s'.", uri
);
647 if (!CanLoadResource(resolved
)) {
648 LogMessageWithContext(resolved
, lineno
, nsIScriptError::warningFlag
,
649 "During chrome registration, cannot register non-local URI '%s' as content.",
654 nsDependentCString
packageName(package
);
655 PackageEntry
* entry
= mPackagesHash
.LookupOrAdd(packageName
);
656 entry
->locales
.SetBase(nsDependentCString(provider
), resolved
);
658 if (mDynamicRegistration
) {
659 ChromePackage chromePackage
;
660 ChromePackageFromPackageEntry(packageName
, entry
, &chromePackage
,
662 SendManifestEntry(chromePackage
);
665 // We use mainPackage as the package we track for reporting new locales being
666 // registered. For most cases it will be "global", but for Fennec it will be
668 nsAutoCString mainPackage
;
669 nsresult rv
= OverrideLocalePackage(NS_LITERAL_CSTRING("global"), mainPackage
);
676 nsChromeRegistryChrome::ManifestSkin(ManifestProcessingContext
& cx
, int lineno
,
677 char *const * argv
, int flags
)
679 char* package
= argv
[0];
680 char* provider
= argv
[1];
683 EnsureLowerCase(package
);
685 nsCOMPtr
<nsIURI
> resolved
= cx
.ResolveURI(uri
);
687 LogMessageWithContext(cx
.GetManifestURI(), lineno
, nsIScriptError::warningFlag
,
688 "During chrome registration, unable to create URI '%s'.", uri
);
692 if (!CanLoadResource(resolved
)) {
693 LogMessageWithContext(resolved
, lineno
, nsIScriptError::warningFlag
,
694 "During chrome registration, cannot register non-local URI '%s' as content.",
699 nsDependentCString
packageName(package
);
700 PackageEntry
* entry
= mPackagesHash
.LookupOrAdd(packageName
);
701 entry
->skins
.SetBase(nsDependentCString(provider
), resolved
);
703 if (mDynamicRegistration
) {
704 ChromePackage chromePackage
;
705 ChromePackageFromPackageEntry(packageName
, entry
, &chromePackage
,
707 SendManifestEntry(chromePackage
);
712 nsChromeRegistryChrome::ManifestOverride(ManifestProcessingContext
& cx
, int lineno
,
713 char *const * argv
, int flags
)
715 char* chrome
= argv
[0];
716 char* resolved
= argv
[1];
718 nsCOMPtr
<nsIURI
> chromeuri
= cx
.ResolveURI(chrome
);
719 nsCOMPtr
<nsIURI
> resolveduri
= cx
.ResolveURI(resolved
);
720 if (!chromeuri
|| !resolveduri
) {
721 LogMessageWithContext(cx
.GetManifestURI(), lineno
, nsIScriptError::warningFlag
,
722 "During chrome registration, unable to create URI.");
726 if (cx
.mType
== NS_SKIN_LOCATION
) {
727 bool chromeSkinOnly
= false;
728 nsresult rv
= chromeuri
->SchemeIs("chrome", &chromeSkinOnly
);
729 chromeSkinOnly
= chromeSkinOnly
&& NS_SUCCEEDED(rv
);
730 if (chromeSkinOnly
) {
731 rv
= resolveduri
->SchemeIs("chrome", &chromeSkinOnly
);
732 chromeSkinOnly
= chromeSkinOnly
&& NS_SUCCEEDED(rv
);
734 if (chromeSkinOnly
) {
735 nsAutoCString chromePath
, resolvedPath
;
736 chromeuri
->GetPathQueryRef(chromePath
);
737 resolveduri
->GetPathQueryRef(resolvedPath
);
738 chromeSkinOnly
= StringBeginsWith(chromePath
, NS_LITERAL_CSTRING("/skin/")) &&
739 StringBeginsWith(resolvedPath
, NS_LITERAL_CSTRING("/skin/"));
741 if (!chromeSkinOnly
) {
742 LogMessageWithContext(cx
.GetManifestURI(), lineno
, nsIScriptError::warningFlag
,
743 "Cannot register non-chrome://.../skin/ URIs '%s' and '%s' as overrides and/or to be overridden from a skin manifest.",
749 if (!CanLoadResource(resolveduri
)) {
750 LogMessageWithContext(cx
.GetManifestURI(), lineno
, nsIScriptError::warningFlag
,
751 "Cannot register non-local URI '%s' for an override.", resolved
);
754 mOverrideTable
.Put(chromeuri
, resolveduri
);
756 if (mDynamicRegistration
) {
757 SerializedURI serializedChrome
;
758 SerializedURI serializedOverride
;
760 SerializeURI(chromeuri
, serializedChrome
);
761 SerializeURI(resolveduri
, serializedOverride
);
763 OverrideMapping override
= { serializedChrome
, serializedOverride
};
764 SendManifestEntry(override
);
769 nsChromeRegistryChrome::ManifestResource(ManifestProcessingContext
& cx
, int lineno
,
770 char *const * argv
, int flags
)
772 char* package
= argv
[0];
775 EnsureLowerCase(package
);
776 nsDependentCString
host(package
);
778 nsCOMPtr
<nsIIOService
> io
= mozilla::services::GetIOService();
780 NS_WARNING("No IO service trying to process chrome manifests");
784 nsCOMPtr
<nsIProtocolHandler
> ph
;
785 nsresult rv
= io
->GetProtocolHandler("resource", getter_AddRefs(ph
));
789 nsCOMPtr
<nsIResProtocolHandler
> rph
= do_QueryInterface(ph
);
791 nsCOMPtr
<nsIURI
> resolved
= cx
.ResolveURI(uri
);
793 LogMessageWithContext(cx
.GetManifestURI(), lineno
, nsIScriptError::warningFlag
,
794 "During chrome registration, unable to create URI '%s'.", uri
);
798 if (!CanLoadResource(resolved
)) {
799 LogMessageWithContext(cx
.GetManifestURI(), lineno
, nsIScriptError::warningFlag
,
800 "Warning: cannot register non-local URI '%s' as a resource.",
805 // By default, Firefox resources are not content-accessible unless the
806 // manifests opts in.
807 bool contentAccessible
= (flags
& nsChromeRegistry::CONTENT_ACCESSIBLE
);
809 uint32_t substitutionFlags
= 0;
810 if (contentAccessible
) {
811 substitutionFlags
|= nsIResProtocolHandler::ALLOW_CONTENT_ACCESS
;
813 rv
= rph
->SetSubstitutionWithFlags(host
, resolved
, substitutionFlags
);
815 LogMessageWithContext(cx
.GetManifestURI(), lineno
, nsIScriptError::warningFlag
,
816 "Warning: cannot set substitution for '%s'.",