chrome/src/nsChromeRegistryChrome.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "mozilla/dom/PContentParent.h"
michael@0 7 #include "RegistryMessageUtils.h"
michael@0 8 #include "nsResProtocolHandler.h"
michael@0 9
michael@0 10 #include "nsChromeRegistryChrome.h"
michael@0 11
michael@0 12 #if defined(XP_WIN)
michael@0 13 #include <windows.h>
michael@0 14 #elif defined(XP_MACOSX)
michael@0 15 #include <CoreServices/CoreServices.h>
michael@0 16 #endif
michael@0 17
michael@0 18 #include "nsArrayEnumerator.h"
michael@0 19 #include "nsComponentManager.h"
michael@0 20 #include "nsEnumeratorUtils.h"
michael@0 21 #include "nsNetUtil.h"
michael@0 22 #include "nsStringEnumerator.h"
michael@0 23 #include "nsTextFormatter.h"
michael@0 24 #include "nsXPCOMCIDInternal.h"
michael@0 25
michael@0 26 #include "mozilla/LookAndFeel.h"
michael@0 27
michael@0 28 #include "nsICommandLine.h"
michael@0 29 #include "nsILocaleService.h"
michael@0 30 #include "nsIObserverService.h"
michael@0 31 #include "nsIPrefBranch.h"
michael@0 32 #include "nsIPrefService.h"
michael@0 33 #include "mozilla/Preferences.h"
michael@0 34 #include "nsIResProtocolHandler.h"
michael@0 35 #include "nsIScriptError.h"
michael@0 36 #include "nsIXPConnect.h"
michael@0 37 #include "nsIXULRuntime.h"
michael@0 38
michael@0 39 #define UILOCALE_CMD_LINE_ARG "UILocale"
michael@0 40
michael@0 41 #define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
michael@0 42 #define SELECTED_LOCALE_PREF "general.useragent.locale"
michael@0 43 #define SELECTED_SKIN_PREF "general.skins.selectedSkin"
michael@0 44 #define PACKAGE_OVERRIDE_BRANCH "chrome.override_package."
michael@0 45
michael@0 46 using namespace mozilla;
michael@0 47
michael@0 48 static PLDHashOperator
michael@0 49 RemoveAll(PLDHashTable *table, PLDHashEntryHdr *entry, uint32_t number, void *arg)
michael@0 50 {
michael@0 51 return (PLDHashOperator) (PL_DHASH_NEXT | PL_DHASH_REMOVE);
michael@0 52 }
michael@0 53
michael@0 54 // We use a "best-fit" algorithm for matching locales and themes.
michael@0 55 // 1) the exact selected locale/theme
michael@0 56 // 2) (locales only) same language, different country
michael@0 57 // e.g. en-GB is the selected locale, only en-US is available
michael@0 58 // 3) any available locale/theme
michael@0 59
michael@0 60 /**
michael@0 61 * Match the language-part of two lang-COUNTRY codes, hopefully but
michael@0 62 * not guaranteed to be in the form ab-CD or abz-CD. "ab" should also
michael@0 63 * work, any other garbage-in will produce undefined results as long
michael@0 64 * as it does not crash.
michael@0 65 */
michael@0 66 static bool
michael@0 67 LanguagesMatch(const nsACString& a, const nsACString& b)
michael@0 68 {
michael@0 69 if (a.Length() < 2 || b.Length() < 2)
michael@0 70 return false;
michael@0 71
michael@0 72 nsACString::const_iterator as, ae, bs, be;
michael@0 73 a.BeginReading(as);
michael@0 74 a.EndReading(ae);
michael@0 75 b.BeginReading(bs);
michael@0 76 b.EndReading(be);
michael@0 77
michael@0 78 while (*as == *bs) {
michael@0 79 if (*as == '-')
michael@0 80 return true;
michael@0 81
michael@0 82 ++as; ++bs;
michael@0 83
michael@0 84 // reached the end
michael@0 85 if (as == ae && bs == be)
michael@0 86 return true;
michael@0 87
michael@0 88 // "a" is short
michael@0 89 if (as == ae)
michael@0 90 return (*bs == '-');
michael@0 91
michael@0 92 // "b" is short
michael@0 93 if (bs == be)
michael@0 94 return (*as == '-');
michael@0 95 }
michael@0 96
michael@0 97 return false;
michael@0 98 }
michael@0 99
michael@0 100 nsChromeRegistryChrome::nsChromeRegistryChrome()
michael@0 101 : mProfileLoaded(false)
michael@0 102 {
michael@0 103 mPackagesHash.ops = nullptr;
michael@0 104 }
michael@0 105
michael@0 106 nsChromeRegistryChrome::~nsChromeRegistryChrome()
michael@0 107 {
michael@0 108 if (mPackagesHash.ops)
michael@0 109 PL_DHashTableFinish(&mPackagesHash);
michael@0 110 }
michael@0 111
michael@0 112 nsresult
michael@0 113 nsChromeRegistryChrome::Init()
michael@0 114 {
michael@0 115 nsresult rv = nsChromeRegistry::Init();
michael@0 116 if (NS_FAILED(rv))
michael@0 117 return rv;
michael@0 118
michael@0 119 mSelectedLocale = NS_LITERAL_CSTRING("en-US");
michael@0 120 mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0");
michael@0 121
michael@0 122 PL_DHashTableInit(&mPackagesHash, &kTableOps,
michael@0 123 nullptr, sizeof(PackageEntry), 16);
michael@0 124
michael@0 125 bool safeMode = false;
michael@0 126 nsCOMPtr<nsIXULRuntime> xulrun (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
michael@0 127 if (xulrun)
michael@0 128 xulrun->GetInSafeMode(&safeMode);
michael@0 129
michael@0 130 nsCOMPtr<nsIPrefService> prefserv (do_GetService(NS_PREFSERVICE_CONTRACTID));
michael@0 131 nsCOMPtr<nsIPrefBranch> prefs;
michael@0 132
michael@0 133 if (safeMode)
michael@0 134 prefserv->GetDefaultBranch(nullptr, getter_AddRefs(prefs));
michael@0 135 else
michael@0 136 prefs = do_QueryInterface(prefserv);
michael@0 137
michael@0 138 if (!prefs) {
michael@0 139 NS_WARNING("Could not get pref service!");
michael@0 140 }
michael@0 141 else {
michael@0 142 nsXPIDLCString provider;
michael@0 143 rv = prefs->GetCharPref(SELECTED_SKIN_PREF, getter_Copies(provider));
michael@0 144 if (NS_SUCCEEDED(rv))
michael@0 145 mSelectedSkin = provider;
michael@0 146
michael@0 147 SelectLocaleFromPref(prefs);
michael@0 148
michael@0 149 rv = prefs->AddObserver(MATCH_OS_LOCALE_PREF, this, true);
michael@0 150 rv = prefs->AddObserver(SELECTED_LOCALE_PREF, this, true);
michael@0 151 rv = prefs->AddObserver(SELECTED_SKIN_PREF, this, true);
michael@0 152 }
michael@0 153
michael@0 154 nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService();
michael@0 155 if (obsService) {
michael@0 156 obsService->AddObserver(this, "command-line-startup", true);
michael@0 157 obsService->AddObserver(this, "profile-initial-state", true);
michael@0 158 }
michael@0 159
michael@0 160 return NS_OK;
michael@0 161 }
michael@0 162
michael@0 163 NS_IMETHODIMP
michael@0 164 nsChromeRegistryChrome::CheckForOSAccessibility()
michael@0 165 {
michael@0 166 int32_t useAccessibilityTheme =
michael@0 167 LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme, 0);
michael@0 168
michael@0 169 if (useAccessibilityTheme) {
michael@0 170 /* Set the skin to classic and remove pref observers */
michael@0 171 if (!mSelectedSkin.EqualsLiteral("classic/1.0")) {
michael@0 172 mSelectedSkin.AssignLiteral("classic/1.0");
michael@0 173 RefreshSkins();
michael@0 174 }
michael@0 175
michael@0 176 nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
michael@0 177 if (prefs) {
michael@0 178 prefs->RemoveObserver(SELECTED_SKIN_PREF, this);
michael@0 179 }
michael@0 180 }
michael@0 181
michael@0 182 return NS_OK;
michael@0 183 }
michael@0 184
michael@0 185 NS_IMETHODIMP
michael@0 186 nsChromeRegistryChrome::GetLocalesForPackage(const nsACString& aPackage,
michael@0 187 nsIUTF8StringEnumerator* *aResult)
michael@0 188 {
michael@0 189 nsCString realpackage;
michael@0 190 nsresult rv = OverrideLocalePackage(aPackage, realpackage);
michael@0 191 if (NS_FAILED(rv))
michael@0 192 return rv;
michael@0 193
michael@0 194 nsTArray<nsCString> *a = new nsTArray<nsCString>;
michael@0 195 if (!a)
michael@0 196 return NS_ERROR_OUT_OF_MEMORY;
michael@0 197
michael@0 198 PackageEntry* entry =
michael@0 199 static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
michael@0 200 & realpackage,
michael@0 201 PL_DHASH_LOOKUP));
michael@0 202
michael@0 203 if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
michael@0 204 entry->locales.EnumerateToArray(a);
michael@0 205 }
michael@0 206
michael@0 207 rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a);
michael@0 208 if (NS_FAILED(rv))
michael@0 209 delete a;
michael@0 210
michael@0 211 return rv;
michael@0 212 }
michael@0 213
michael@0 214 static nsresult
michael@0 215 getUILangCountry(nsACString& aUILang)
michael@0 216 {
michael@0 217 nsresult rv;
michael@0 218
michael@0 219 nsCOMPtr<nsILocaleService> localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
michael@0 220 NS_ENSURE_SUCCESS(rv, rv);
michael@0 221
michael@0 222 nsAutoString uiLang;
michael@0 223 rv = localeService->GetLocaleComponentForUserAgent(uiLang);
michael@0 224 NS_ENSURE_SUCCESS(rv, rv);
michael@0 225
michael@0 226 CopyUTF16toUTF8(uiLang, aUILang);
michael@0 227 return NS_OK;
michael@0 228 }
michael@0 229
michael@0 230 NS_IMETHODIMP
michael@0 231 nsChromeRegistryChrome::IsLocaleRTL(const nsACString& package, bool *aResult)
michael@0 232 {
michael@0 233 *aResult = false;
michael@0 234
michael@0 235 nsAutoCString locale;
michael@0 236 GetSelectedLocale(package, locale);
michael@0 237 if (locale.Length() < 2)
michael@0 238 return NS_OK;
michael@0 239
michael@0 240 // first check the intl.uidirection.<locale> preference, and if that is not
michael@0 241 // set, check the same preference but with just the first two characters of
michael@0 242 // the locale. If that isn't set, default to left-to-right.
michael@0 243 nsAutoCString prefString = NS_LITERAL_CSTRING("intl.uidirection.") + locale;
michael@0 244 nsCOMPtr<nsIPrefBranch> prefBranch (do_GetService(NS_PREFSERVICE_CONTRACTID));
michael@0 245 if (!prefBranch)
michael@0 246 return NS_OK;
michael@0 247
michael@0 248 nsXPIDLCString dir;
michael@0 249 prefBranch->GetCharPref(prefString.get(), getter_Copies(dir));
michael@0 250 if (dir.IsEmpty()) {
michael@0 251 int32_t hyphen = prefString.FindChar('-');
michael@0 252 if (hyphen >= 1) {
michael@0 253 nsAutoCString shortPref(Substring(prefString, 0, hyphen));
michael@0 254 prefBranch->GetCharPref(shortPref.get(), getter_Copies(dir));
michael@0 255 }
michael@0 256 }
michael@0 257 *aResult = dir.EqualsLiteral("rtl");
michael@0 258 return NS_OK;
michael@0 259 }
michael@0 260
michael@0 261 nsresult
michael@0 262 nsChromeRegistryChrome::GetSelectedLocale(const nsACString& aPackage,
michael@0 263 nsACString& aLocale)
michael@0 264 {
michael@0 265 nsCString realpackage;
michael@0 266 nsresult rv = OverrideLocalePackage(aPackage, realpackage);
michael@0 267 if (NS_FAILED(rv))
michael@0 268 return rv;
michael@0 269 PackageEntry* entry =
michael@0 270 static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
michael@0 271 & realpackage,
michael@0 272 PL_DHASH_LOOKUP));
michael@0 273
michael@0 274 if (PL_DHASH_ENTRY_IS_FREE(entry))
michael@0 275 return NS_ERROR_FAILURE;
michael@0 276
michael@0 277 aLocale = entry->locales.GetSelected(mSelectedLocale, nsProviderArray::LOCALE);
michael@0 278 if (aLocale.IsEmpty())
michael@0 279 return NS_ERROR_FAILURE;
michael@0 280
michael@0 281 return NS_OK;
michael@0 282 }
michael@0 283
michael@0 284 nsresult
michael@0 285 nsChromeRegistryChrome::OverrideLocalePackage(const nsACString& aPackage,
michael@0 286 nsACString& aOverride)
michael@0 287 {
michael@0 288 const nsACString& pref = NS_LITERAL_CSTRING(PACKAGE_OVERRIDE_BRANCH) + aPackage;
michael@0 289 nsAdoptingCString override = mozilla::Preferences::GetCString(PromiseFlatCString(pref).get());
michael@0 290 if (override) {
michael@0 291 aOverride = override;
michael@0 292 }
michael@0 293 else {
michael@0 294 aOverride = aPackage;
michael@0 295 }
michael@0 296 return NS_OK;
michael@0 297 }
michael@0 298
michael@0 299 nsresult
michael@0 300 nsChromeRegistryChrome::SelectLocaleFromPref(nsIPrefBranch* prefs)
michael@0 301 {
michael@0 302 nsresult rv;
michael@0 303 bool matchOSLocale = false;
michael@0 304 rv = prefs->GetBoolPref(MATCH_OS_LOCALE_PREF, &matchOSLocale);
michael@0 305
michael@0 306 if (NS_SUCCEEDED(rv) && matchOSLocale) {
michael@0 307 // compute lang and region code only when needed!
michael@0 308 nsAutoCString uiLocale;
michael@0 309 rv = getUILangCountry(uiLocale);
michael@0 310 if (NS_SUCCEEDED(rv))
michael@0 311 mSelectedLocale = uiLocale;
michael@0 312 }
michael@0 313 else {
michael@0 314 nsXPIDLCString provider;
michael@0 315 rv = prefs->GetCharPref(SELECTED_LOCALE_PREF, getter_Copies(provider));
michael@0 316 if (NS_SUCCEEDED(rv)) {
michael@0 317 mSelectedLocale = provider;
michael@0 318 }
michael@0 319 }
michael@0 320
michael@0 321 if (NS_FAILED(rv))
michael@0 322 NS_ERROR("Couldn't select locale from pref!");
michael@0 323
michael@0 324 return rv;
michael@0 325 }
michael@0 326
michael@0 327 NS_IMETHODIMP
michael@0 328 nsChromeRegistryChrome::Observe(nsISupports *aSubject, const char *aTopic,
michael@0 329 const char16_t *someData)
michael@0 330 {
michael@0 331 nsresult rv = NS_OK;
michael@0 332
michael@0 333 if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
michael@0 334 nsCOMPtr<nsIPrefBranch> prefs (do_QueryInterface(aSubject));
michael@0 335 NS_ASSERTION(prefs, "Bad observer call!");
michael@0 336
michael@0 337 NS_ConvertUTF16toUTF8 pref(someData);
michael@0 338
michael@0 339 if (pref.EqualsLiteral(MATCH_OS_LOCALE_PREF) ||
michael@0 340 pref.EqualsLiteral(SELECTED_LOCALE_PREF)) {
michael@0 341 rv = UpdateSelectedLocale();
michael@0 342 if (NS_SUCCEEDED(rv) && mProfileLoaded)
michael@0 343 FlushAllCaches();
michael@0 344 }
michael@0 345 else if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
michael@0 346 nsXPIDLCString provider;
michael@0 347 rv = prefs->GetCharPref(pref.get(), getter_Copies(provider));
michael@0 348 if (NS_FAILED(rv)) {
michael@0 349 NS_ERROR("Couldn't get new skin pref!");
michael@0 350 return rv;
michael@0 351 }
michael@0 352
michael@0 353 mSelectedSkin = provider;
michael@0 354 RefreshSkins();
michael@0 355 } else {
michael@0 356 NS_ERROR("Unexpected pref!");
michael@0 357 }
michael@0 358 }
michael@0 359 else if (!strcmp("command-line-startup", aTopic)) {
michael@0 360 nsCOMPtr<nsICommandLine> cmdLine (do_QueryInterface(aSubject));
michael@0 361 if (cmdLine) {
michael@0 362 nsAutoString uiLocale;
michael@0 363 rv = cmdLine->HandleFlagWithParam(NS_LITERAL_STRING(UILOCALE_CMD_LINE_ARG),
michael@0 364 false, uiLocale);
michael@0 365 if (NS_SUCCEEDED(rv) && !uiLocale.IsEmpty()) {
michael@0 366 CopyUTF16toUTF8(uiLocale, mSelectedLocale);
michael@0 367 nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
michael@0 368 if (prefs) {
michael@0 369 prefs->RemoveObserver(SELECTED_LOCALE_PREF, this);
michael@0 370 }
michael@0 371 }
michael@0 372 }
michael@0 373 }
michael@0 374 else if (!strcmp("profile-initial-state", aTopic)) {
michael@0 375 mProfileLoaded = true;
michael@0 376 }
michael@0 377 else {
michael@0 378 NS_ERROR("Unexpected observer topic!");
michael@0 379 }
michael@0 380
michael@0 381 return rv;
michael@0 382 }
michael@0 383
michael@0 384 NS_IMETHODIMP
michael@0 385 nsChromeRegistryChrome::CheckForNewChrome()
michael@0 386 {
michael@0 387 PL_DHashTableEnumerate(&mPackagesHash, RemoveAll, nullptr);
michael@0 388 mOverlayHash.Clear();
michael@0 389 mStyleHash.Clear();
michael@0 390 mOverrideTable.Clear();
michael@0 391
michael@0 392 nsComponentManagerImpl::gComponentManager->RereadChromeManifests();
michael@0 393 return NS_OK;
michael@0 394 }
michael@0 395
michael@0 396 nsresult nsChromeRegistryChrome::UpdateSelectedLocale()
michael@0 397 {
michael@0 398 nsresult rv = NS_OK;
michael@0 399 nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
michael@0 400 if (prefs) {
michael@0 401 rv = SelectLocaleFromPref(prefs);
michael@0 402 if (NS_SUCCEEDED(rv)) {
michael@0 403 nsCOMPtr<nsIObserverService> obsSvc =
michael@0 404 mozilla::services::GetObserverService();
michael@0 405 NS_ASSERTION(obsSvc, "Couldn't get observer service.");
michael@0 406 obsSvc->NotifyObservers((nsIChromeRegistry*) this,
michael@0 407 "selected-locale-has-changed", nullptr);
michael@0 408 }
michael@0 409 }
michael@0 410
michael@0 411 return rv;
michael@0 412 }
michael@0 413
michael@0 414 static void
michael@0 415 SerializeURI(nsIURI* aURI,
michael@0 416 SerializedURI& aSerializedURI)
michael@0 417 {
michael@0 418 if (!aURI)
michael@0 419 return;
michael@0 420
michael@0 421 aURI->GetSpec(aSerializedURI.spec);
michael@0 422 aURI->GetOriginCharset(aSerializedURI.charset);
michael@0 423 }
michael@0 424
michael@0 425 static PLDHashOperator
michael@0 426 EnumerateOverride(nsIURI* aURIKey,
michael@0 427 nsIURI* aURI,
michael@0 428 void* aArg)
michael@0 429 {
michael@0 430 nsTArray<OverrideMapping>* overrides =
michael@0 431 static_cast<nsTArray<OverrideMapping>*>(aArg);
michael@0 432
michael@0 433 SerializedURI chromeURI, overrideURI;
michael@0 434
michael@0 435 SerializeURI(aURIKey, chromeURI);
michael@0 436 SerializeURI(aURI, overrideURI);
michael@0 437
michael@0 438 OverrideMapping override = {
michael@0 439 chromeURI, overrideURI
michael@0 440 };
michael@0 441 overrides->AppendElement(override);
michael@0 442 return (PLDHashOperator)PL_DHASH_NEXT;
michael@0 443 }
michael@0 444
michael@0 445 struct EnumerationArgs
michael@0 446 {
michael@0 447 InfallibleTArray<ChromePackage>& packages;
michael@0 448 const nsCString& selectedLocale;
michael@0 449 const nsCString& selectedSkin;
michael@0 450 };
michael@0 451
michael@0 452 void
michael@0 453 nsChromeRegistryChrome::SendRegisteredChrome(
michael@0 454 mozilla::dom::PContentParent* aParent)
michael@0 455 {
michael@0 456 InfallibleTArray<ChromePackage> packages;
michael@0 457 InfallibleTArray<ResourceMapping> resources;
michael@0 458 InfallibleTArray<OverrideMapping> overrides;
michael@0 459
michael@0 460 EnumerationArgs args = {
michael@0 461 packages, mSelectedLocale, mSelectedSkin
michael@0 462 };
michael@0 463 PL_DHashTableEnumerate(&mPackagesHash, CollectPackages, &args);
michael@0 464
michael@0 465 nsCOMPtr<nsIIOService> io (do_GetIOService());
michael@0 466 NS_ENSURE_TRUE_VOID(io);
michael@0 467
michael@0 468 nsCOMPtr<nsIProtocolHandler> ph;
michael@0 469 nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
michael@0 470 NS_ENSURE_SUCCESS_VOID(rv);
michael@0 471
michael@0 472 //FIXME: Some substitutions are set up lazily and might not exist yet
michael@0 473 nsCOMPtr<nsIResProtocolHandler> irph (do_QueryInterface(ph));
michael@0 474 nsResProtocolHandler* rph = static_cast<nsResProtocolHandler*>(irph.get());
michael@0 475 rph->CollectSubstitutions(resources);
michael@0 476
michael@0 477 mOverrideTable.EnumerateRead(&EnumerateOverride, &overrides);
michael@0 478
michael@0 479 bool success = aParent->SendRegisterChrome(packages, resources, overrides,
michael@0 480 mSelectedLocale);
michael@0 481 NS_ENSURE_TRUE_VOID(success);
michael@0 482 }
michael@0 483
michael@0 484 PLDHashOperator
michael@0 485 nsChromeRegistryChrome::CollectPackages(PLDHashTable *table,
michael@0 486 PLDHashEntryHdr *entry,
michael@0 487 uint32_t number,
michael@0 488 void *arg)
michael@0 489 {
michael@0 490 EnumerationArgs* args = static_cast<EnumerationArgs*>(arg);
michael@0 491 PackageEntry* package = static_cast<PackageEntry*>(entry);
michael@0 492
michael@0 493 SerializedURI contentURI, localeURI, skinURI;
michael@0 494
michael@0 495 SerializeURI(package->baseURI, contentURI);
michael@0 496 SerializeURI(package->locales.GetBase(args->selectedLocale,
michael@0 497 nsProviderArray::LOCALE), localeURI);
michael@0 498 SerializeURI(package->skins.GetBase(args->selectedSkin, nsProviderArray::ANY),
michael@0 499 skinURI);
michael@0 500
michael@0 501 ChromePackage chromePackage = {
michael@0 502 package->package,
michael@0 503 contentURI,
michael@0 504 localeURI,
michael@0 505 skinURI,
michael@0 506 package->flags
michael@0 507 };
michael@0 508 args->packages.AppendElement(chromePackage);
michael@0 509 return (PLDHashOperator)PL_DHASH_NEXT;
michael@0 510 }
michael@0 511
michael@0 512 static bool
michael@0 513 CanLoadResource(nsIURI* aResourceURI)
michael@0 514 {
michael@0 515 bool isLocalResource = false;
michael@0 516 (void)NS_URIChainHasFlags(aResourceURI,
michael@0 517 nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
michael@0 518 &isLocalResource);
michael@0 519 return isLocalResource;
michael@0 520 }
michael@0 521
michael@0 522 nsIURI*
michael@0 523 nsChromeRegistryChrome::GetBaseURIFromPackage(const nsCString& aPackage,
michael@0 524 const nsCString& aProvider,
michael@0 525 const nsCString& aPath)
michael@0 526 {
michael@0 527 PackageEntry* entry =
michael@0 528 static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
michael@0 529 &aPackage,
michael@0 530 PL_DHASH_LOOKUP));
michael@0 531
michael@0 532 if (PL_DHASH_ENTRY_IS_FREE(entry)) {
michael@0 533 if (!mInitialized)
michael@0 534 return nullptr;
michael@0 535
michael@0 536 LogMessage("No chrome package registered for chrome://%s/%s/%s",
michael@0 537 aPackage.get(), aProvider.get(), aPath.get());
michael@0 538
michael@0 539 return nullptr;
michael@0 540 }
michael@0 541
michael@0 542 if (aProvider.EqualsLiteral("locale")) {
michael@0 543 return entry->locales.GetBase(mSelectedLocale, nsProviderArray::LOCALE);
michael@0 544 }
michael@0 545 else if (aProvider.EqualsLiteral("skin")) {
michael@0 546 return entry->skins.GetBase(mSelectedSkin, nsProviderArray::ANY);
michael@0 547 }
michael@0 548 else if (aProvider.EqualsLiteral("content")) {
michael@0 549 return entry->baseURI;
michael@0 550 }
michael@0 551 return nullptr;
michael@0 552 }
michael@0 553
michael@0 554 nsresult
michael@0 555 nsChromeRegistryChrome::GetFlagsFromPackage(const nsCString& aPackage,
michael@0 556 uint32_t* aFlags)
michael@0 557 {
michael@0 558 PackageEntry* entry =
michael@0 559 static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
michael@0 560 & (nsACString&) aPackage,
michael@0 561 PL_DHASH_LOOKUP));
michael@0 562 if (PL_DHASH_ENTRY_IS_FREE(entry))
michael@0 563 return NS_ERROR_NOT_AVAILABLE;
michael@0 564
michael@0 565 *aFlags = entry->flags;
michael@0 566 return NS_OK;
michael@0 567 }
michael@0 568
michael@0 569 PLHashNumber
michael@0 570 nsChromeRegistryChrome::HashKey(PLDHashTable *table, const void *key)
michael@0 571 {
michael@0 572 const nsACString& str = *reinterpret_cast<const nsACString*>(key);
michael@0 573 return HashString(str);
michael@0 574 }
michael@0 575
michael@0 576 bool
michael@0 577 nsChromeRegistryChrome::MatchKey(PLDHashTable *table, const PLDHashEntryHdr *entry,
michael@0 578 const void *key)
michael@0 579 {
michael@0 580 const nsACString& str = *reinterpret_cast<const nsACString*>(key);
michael@0 581 const PackageEntry* pentry = static_cast<const PackageEntry*>(entry);
michael@0 582 return str.Equals(pentry->package);
michael@0 583 }
michael@0 584
michael@0 585 void
michael@0 586 nsChromeRegistryChrome::ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
michael@0 587 {
michael@0 588 PackageEntry* pentry = static_cast<PackageEntry*>(entry);
michael@0 589 pentry->~PackageEntry();
michael@0 590 }
michael@0 591
michael@0 592 bool
michael@0 593 nsChromeRegistryChrome::InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
michael@0 594 const void *key)
michael@0 595 {
michael@0 596 const nsACString& str = *reinterpret_cast<const nsACString*>(key);
michael@0 597
michael@0 598 new (entry) PackageEntry(str);
michael@0 599 return true;
michael@0 600 }
michael@0 601
michael@0 602 const PLDHashTableOps
michael@0 603 nsChromeRegistryChrome::kTableOps = {
michael@0 604 PL_DHashAllocTable,
michael@0 605 PL_DHashFreeTable,
michael@0 606 HashKey,
michael@0 607 MatchKey,
michael@0 608 PL_DHashMoveEntryStub,
michael@0 609 ClearEntry,
michael@0 610 PL_DHashFinalizeStub,
michael@0 611 InitEntry
michael@0 612 };
michael@0 613
michael@0 614 nsChromeRegistryChrome::ProviderEntry*
michael@0 615 nsChromeRegistryChrome::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
michael@0 616 {
michael@0 617 int32_t i = mArray.Count();
michael@0 618 if (!i)
michael@0 619 return nullptr;
michael@0 620
michael@0 621 ProviderEntry* found = nullptr; // Only set if we find a partial-match locale
michael@0 622 ProviderEntry* entry;
michael@0 623
michael@0 624 while (i--) {
michael@0 625 entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
michael@0 626 if (aPreferred.Equals(entry->provider))
michael@0 627 return entry;
michael@0 628
michael@0 629 if (aType != LOCALE)
michael@0 630 continue;
michael@0 631
michael@0 632 if (LanguagesMatch(aPreferred, entry->provider)) {
michael@0 633 found = entry;
michael@0 634 continue;
michael@0 635 }
michael@0 636
michael@0 637 if (!found && entry->provider.EqualsLiteral("en-US"))
michael@0 638 found = entry;
michael@0 639 }
michael@0 640
michael@0 641 if (!found && aType != EXACT)
michael@0 642 return entry;
michael@0 643
michael@0 644 return found;
michael@0 645 }
michael@0 646
michael@0 647 nsIURI*
michael@0 648 nsChromeRegistryChrome::nsProviderArray::GetBase(const nsACString& aPreferred, MatchType aType)
michael@0 649 {
michael@0 650 ProviderEntry* provider = GetProvider(aPreferred, aType);
michael@0 651
michael@0 652 if (!provider)
michael@0 653 return nullptr;
michael@0 654
michael@0 655 return provider->baseURI;
michael@0 656 }
michael@0 657
michael@0 658 const nsACString&
michael@0 659 nsChromeRegistryChrome::nsProviderArray::GetSelected(const nsACString& aPreferred, MatchType aType)
michael@0 660 {
michael@0 661 ProviderEntry* entry = GetProvider(aPreferred, aType);
michael@0 662
michael@0 663 if (entry)
michael@0 664 return entry->provider;
michael@0 665
michael@0 666 return EmptyCString();
michael@0 667 }
michael@0 668
michael@0 669 void
michael@0 670 nsChromeRegistryChrome::nsProviderArray::SetBase(const nsACString& aProvider, nsIURI* aBaseURL)
michael@0 671 {
michael@0 672 ProviderEntry* provider = GetProvider(aProvider, EXACT);
michael@0 673
michael@0 674 if (provider) {
michael@0 675 provider->baseURI = aBaseURL;
michael@0 676 return;
michael@0 677 }
michael@0 678
michael@0 679 // no existing entries, add a new one
michael@0 680 provider = new ProviderEntry(aProvider, aBaseURL);
michael@0 681 if (!provider)
michael@0 682 return; // It's safe to silently fail on OOM
michael@0 683
michael@0 684 mArray.AppendElement(provider);
michael@0 685 }
michael@0 686
michael@0 687 void
michael@0 688 nsChromeRegistryChrome::nsProviderArray::EnumerateToArray(nsTArray<nsCString> *a)
michael@0 689 {
michael@0 690 int32_t i = mArray.Count();
michael@0 691 while (i--) {
michael@0 692 ProviderEntry *entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
michael@0 693 a->AppendElement(entry->provider);
michael@0 694 }
michael@0 695 }
michael@0 696
michael@0 697 void
michael@0 698 nsChromeRegistryChrome::nsProviderArray::Clear()
michael@0 699 {
michael@0 700 int32_t i = mArray.Count();
michael@0 701 while (i--) {
michael@0 702 ProviderEntry* entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
michael@0 703 delete entry;
michael@0 704 }
michael@0 705
michael@0 706 mArray.Clear();
michael@0 707 }
michael@0 708
michael@0 709 void
michael@0 710 nsChromeRegistryChrome::OverlayListEntry::AddURI(nsIURI* aURI)
michael@0 711 {
michael@0 712 int32_t i = mArray.Count();
michael@0 713 while (i--) {
michael@0 714 bool equals;
michael@0 715 if (NS_SUCCEEDED(aURI->Equals(mArray[i], &equals)) && equals)
michael@0 716 return;
michael@0 717 }
michael@0 718
michael@0 719 mArray.AppendObject(aURI);
michael@0 720 }
michael@0 721
michael@0 722 void
michael@0 723 nsChromeRegistryChrome::OverlayListHash::Add(nsIURI* aBase, nsIURI* aOverlay)
michael@0 724 {
michael@0 725 OverlayListEntry* entry = mTable.PutEntry(aBase);
michael@0 726 if (entry)
michael@0 727 entry->AddURI(aOverlay);
michael@0 728 }
michael@0 729
michael@0 730 const nsCOMArray<nsIURI>*
michael@0 731 nsChromeRegistryChrome::OverlayListHash::GetArray(nsIURI* aBase)
michael@0 732 {
michael@0 733 OverlayListEntry* entry = mTable.GetEntry(aBase);
michael@0 734 if (!entry)
michael@0 735 return nullptr;
michael@0 736
michael@0 737 return &entry->mArray;
michael@0 738 }
michael@0 739
michael@0 740 #ifdef MOZ_XUL
michael@0 741 NS_IMETHODIMP
michael@0 742 nsChromeRegistryChrome::GetStyleOverlays(nsIURI *aChromeURL,
michael@0 743 nsISimpleEnumerator **aResult)
michael@0 744 {
michael@0 745 const nsCOMArray<nsIURI>* parray = mStyleHash.GetArray(aChromeURL);
michael@0 746 if (!parray)
michael@0 747 return NS_NewEmptyEnumerator(aResult);
michael@0 748
michael@0 749 return NS_NewArrayEnumerator(aResult, *parray);
michael@0 750 }
michael@0 751
michael@0 752 NS_IMETHODIMP
michael@0 753 nsChromeRegistryChrome::GetXULOverlays(nsIURI *aChromeURL,
michael@0 754 nsISimpleEnumerator **aResult)
michael@0 755 {
michael@0 756 const nsCOMArray<nsIURI>* parray = mOverlayHash.GetArray(aChromeURL);
michael@0 757 if (!parray)
michael@0 758 return NS_NewEmptyEnumerator(aResult);
michael@0 759
michael@0 760 return NS_NewArrayEnumerator(aResult, *parray);
michael@0 761 }
michael@0 762 #endif // MOZ_XUL
michael@0 763
michael@0 764 nsIURI*
michael@0 765 nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
michael@0 766 {
michael@0 767 if (!mManifestURI) {
michael@0 768 nsCString uri;
michael@0 769 mFile.GetURIString(uri);
michael@0 770 NS_NewURI(getter_AddRefs(mManifestURI), uri);
michael@0 771 }
michael@0 772 return mManifestURI;
michael@0 773 }
michael@0 774
michael@0 775 nsIXPConnect*
michael@0 776 nsChromeRegistry::ManifestProcessingContext::GetXPConnect()
michael@0 777 {
michael@0 778 if (!mXPConnect)
michael@0 779 mXPConnect = do_GetService("@mozilla.org/js/xpc/XPConnect;1");
michael@0 780
michael@0 781 return mXPConnect;
michael@0 782 }
michael@0 783
michael@0 784 already_AddRefed<nsIURI>
michael@0 785 nsChromeRegistry::ManifestProcessingContext::ResolveURI(const char* uri)
michael@0 786 {
michael@0 787 nsIURI* baseuri = GetManifestURI();
michael@0 788 if (!baseuri)
michael@0 789 return nullptr;
michael@0 790
michael@0 791 nsCOMPtr<nsIURI> resolved;
michael@0 792 nsresult rv = NS_NewURI(getter_AddRefs(resolved), uri, baseuri);
michael@0 793 if (NS_FAILED(rv))
michael@0 794 return nullptr;
michael@0 795
michael@0 796 return resolved.forget();
michael@0 797 }
michael@0 798
michael@0 799 static void
michael@0 800 EnsureLowerCase(char *aBuf)
michael@0 801 {
michael@0 802 for (; *aBuf; ++aBuf) {
michael@0 803 char ch = *aBuf;
michael@0 804 if (ch >= 'A' && ch <= 'Z')
michael@0 805 *aBuf = ch + 'a' - 'A';
michael@0 806 }
michael@0 807 }
michael@0 808
michael@0 809 void
michael@0 810 nsChromeRegistryChrome::ManifestContent(ManifestProcessingContext& cx, int lineno,
michael@0 811 char *const * argv, bool platform,
michael@0 812 bool contentaccessible)
michael@0 813 {
michael@0 814 char* package = argv[0];
michael@0 815 char* uri = argv[1];
michael@0 816
michael@0 817 EnsureLowerCase(package);
michael@0 818
michael@0 819 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
michael@0 820 if (!resolved) {
michael@0 821 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 822 "During chrome registration, unable to create URI '%s'.", uri);
michael@0 823 return;
michael@0 824 }
michael@0 825
michael@0 826 if (!CanLoadResource(resolved)) {
michael@0 827 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
michael@0 828 "During chrome registration, cannot register non-local URI '%s' as content.",
michael@0 829 uri);
michael@0 830 return;
michael@0 831 }
michael@0 832
michael@0 833 PackageEntry* entry =
michael@0 834 static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
michael@0 835 & (const nsACString&) nsDependentCString(package),
michael@0 836 PL_DHASH_ADD));
michael@0 837 if (!entry)
michael@0 838 return;
michael@0 839
michael@0 840 entry->baseURI = resolved;
michael@0 841
michael@0 842 if (platform)
michael@0 843 entry->flags |= PLATFORM_PACKAGE;
michael@0 844 if (contentaccessible)
michael@0 845 entry->flags |= CONTENT_ACCESSIBLE;
michael@0 846 }
michael@0 847
michael@0 848 void
michael@0 849 nsChromeRegistryChrome::ManifestLocale(ManifestProcessingContext& cx, int lineno,
michael@0 850 char *const * argv, bool platform,
michael@0 851 bool contentaccessible)
michael@0 852 {
michael@0 853 char* package = argv[0];
michael@0 854 char* provider = argv[1];
michael@0 855 char* uri = argv[2];
michael@0 856
michael@0 857 EnsureLowerCase(package);
michael@0 858
michael@0 859 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
michael@0 860 if (!resolved) {
michael@0 861 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 862 "During chrome registration, unable to create URI '%s'.", uri);
michael@0 863 return;
michael@0 864 }
michael@0 865
michael@0 866 if (!CanLoadResource(resolved)) {
michael@0 867 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
michael@0 868 "During chrome registration, cannot register non-local URI '%s' as content.",
michael@0 869 uri);
michael@0 870 return;
michael@0 871 }
michael@0 872
michael@0 873 PackageEntry* entry =
michael@0 874 static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
michael@0 875 & (const nsACString&) nsDependentCString(package),
michael@0 876 PL_DHASH_ADD));
michael@0 877 if (!entry)
michael@0 878 return;
michael@0 879
michael@0 880 entry->locales.SetBase(nsDependentCString(provider), resolved);
michael@0 881 }
michael@0 882
michael@0 883 void
michael@0 884 nsChromeRegistryChrome::ManifestSkin(ManifestProcessingContext& cx, int lineno,
michael@0 885 char *const * argv, bool platform,
michael@0 886 bool contentaccessible)
michael@0 887 {
michael@0 888 char* package = argv[0];
michael@0 889 char* provider = argv[1];
michael@0 890 char* uri = argv[2];
michael@0 891
michael@0 892 EnsureLowerCase(package);
michael@0 893
michael@0 894 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
michael@0 895 if (!resolved) {
michael@0 896 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 897 "During chrome registration, unable to create URI '%s'.", uri);
michael@0 898 return;
michael@0 899 }
michael@0 900
michael@0 901 if (!CanLoadResource(resolved)) {
michael@0 902 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
michael@0 903 "During chrome registration, cannot register non-local URI '%s' as content.",
michael@0 904 uri);
michael@0 905 return;
michael@0 906 }
michael@0 907
michael@0 908 PackageEntry* entry =
michael@0 909 static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
michael@0 910 & (const nsACString&) nsDependentCString(package),
michael@0 911 PL_DHASH_ADD));
michael@0 912 if (!entry)
michael@0 913 return;
michael@0 914
michael@0 915 entry->skins.SetBase(nsDependentCString(provider), resolved);
michael@0 916 }
michael@0 917
michael@0 918 void
michael@0 919 nsChromeRegistryChrome::ManifestOverlay(ManifestProcessingContext& cx, int lineno,
michael@0 920 char *const * argv, bool platform,
michael@0 921 bool contentaccessible)
michael@0 922 {
michael@0 923 char* base = argv[0];
michael@0 924 char* overlay = argv[1];
michael@0 925
michael@0 926 nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
michael@0 927 nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
michael@0 928 if (!baseuri || !overlayuri) {
michael@0 929 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 930 "During chrome registration, unable to create URI.");
michael@0 931 return;
michael@0 932 }
michael@0 933
michael@0 934 if (!CanLoadResource(overlayuri)) {
michael@0 935 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 936 "Cannot register non-local URI '%s' as an overlay.", overlay);
michael@0 937 return;
michael@0 938 }
michael@0 939
michael@0 940 mOverlayHash.Add(baseuri, overlayuri);
michael@0 941 }
michael@0 942
michael@0 943 void
michael@0 944 nsChromeRegistryChrome::ManifestStyle(ManifestProcessingContext& cx, int lineno,
michael@0 945 char *const * argv, bool platform,
michael@0 946 bool contentaccessible)
michael@0 947 {
michael@0 948 char* base = argv[0];
michael@0 949 char* overlay = argv[1];
michael@0 950
michael@0 951 nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
michael@0 952 nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
michael@0 953 if (!baseuri || !overlayuri) {
michael@0 954 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 955 "During chrome registration, unable to create URI.");
michael@0 956 return;
michael@0 957 }
michael@0 958
michael@0 959 if (!CanLoadResource(overlayuri)) {
michael@0 960 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 961 "Cannot register non-local URI '%s' as a style overlay.", overlay);
michael@0 962 return;
michael@0 963 }
michael@0 964
michael@0 965 mStyleHash.Add(baseuri, overlayuri);
michael@0 966 }
michael@0 967
michael@0 968 void
michael@0 969 nsChromeRegistryChrome::ManifestOverride(ManifestProcessingContext& cx, int lineno,
michael@0 970 char *const * argv, bool platform,
michael@0 971 bool contentaccessible)
michael@0 972 {
michael@0 973 char* chrome = argv[0];
michael@0 974 char* resolved = argv[1];
michael@0 975
michael@0 976 nsCOMPtr<nsIURI> chromeuri = cx.ResolveURI(chrome);
michael@0 977 nsCOMPtr<nsIURI> resolveduri = cx.ResolveURI(resolved);
michael@0 978 if (!chromeuri || !resolveduri) {
michael@0 979 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 980 "During chrome registration, unable to create URI.");
michael@0 981 return;
michael@0 982 }
michael@0 983
michael@0 984 if (!CanLoadResource(resolveduri)) {
michael@0 985 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 986 "Cannot register non-local URI '%s' for an override.", resolved);
michael@0 987 return;
michael@0 988 }
michael@0 989 mOverrideTable.Put(chromeuri, resolveduri);
michael@0 990 }
michael@0 991
michael@0 992 void
michael@0 993 nsChromeRegistryChrome::ManifestResource(ManifestProcessingContext& cx, int lineno,
michael@0 994 char *const * argv, bool platform,
michael@0 995 bool contentaccessible)
michael@0 996 {
michael@0 997 char* package = argv[0];
michael@0 998 char* uri = argv[1];
michael@0 999
michael@0 1000 EnsureLowerCase(package);
michael@0 1001 nsDependentCString host(package);
michael@0 1002
michael@0 1003 nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
michael@0 1004 if (!io) {
michael@0 1005 NS_WARNING("No IO service trying to process chrome manifests");
michael@0 1006 return;
michael@0 1007 }
michael@0 1008
michael@0 1009 nsCOMPtr<nsIProtocolHandler> ph;
michael@0 1010 nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
michael@0 1011 if (NS_FAILED(rv))
michael@0 1012 return;
michael@0 1013
michael@0 1014 nsCOMPtr<nsIResProtocolHandler> rph = do_QueryInterface(ph);
michael@0 1015
michael@0 1016 bool exists = false;
michael@0 1017 rv = rph->HasSubstitution(host, &exists);
michael@0 1018 if (exists) {
michael@0 1019 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 1020 "Duplicate resource declaration for '%s' ignored.", package);
michael@0 1021 return;
michael@0 1022 }
michael@0 1023
michael@0 1024 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
michael@0 1025 if (!resolved) {
michael@0 1026 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 1027 "During chrome registration, unable to create URI '%s'.", uri);
michael@0 1028 return;
michael@0 1029 }
michael@0 1030
michael@0 1031 if (!CanLoadResource(resolved)) {
michael@0 1032 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
michael@0 1033 "Warning: cannot register non-local URI '%s' as a resource.",
michael@0 1034 uri);
michael@0 1035 return;
michael@0 1036 }
michael@0 1037
michael@0 1038 rph->SetSubstitution(host, resolved);
michael@0 1039 }

mercurial