1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et tw=78: */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is mozilla.org code.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
24 * Original Author: David W. Hyatt (hyatt@netscape.com)
25 * Gagan Saksena <gagan@netscape.com>
26 * Benjamin Smedberg <benjamin@smedbergs.us>
28 * Alternatively, the contents of this file may be used under the terms of
29 * either the GNU General Public License Version 2 or later (the "GPL"), or
30 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the MPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the MPL, the GPL or the LGPL.
40 * ***** END LICENSE BLOCK ***** */
42 #include "nsChromeRegistry.h"
50 #elif defined(XP_MACOSX)
51 #include <Carbon/Carbon.h>
52 #elif defined(MOZ_WIDGET_GTK2)
56 #include "nsAppDirectoryServiceDefs.h"
57 #include "nsArrayEnumerator.h"
58 #include "nsStringEnumerator.h"
59 #include "nsEnumeratorUtils.h"
61 #include "nsDOMError.h"
64 #include "nsLayoutCID.h"
66 #include "nsNetUtil.h"
67 #include "nsReadableUtils.h"
68 #include "nsStaticAtom.h"
70 #include "nsUnicharUtils.h"
71 #include "nsWidgetsCID.h"
72 #include "nsXPIDLString.h"
73 #include "nsXULAppAPI.h"
74 #include "nsTextFormatter.h"
77 #include "nsICommandLine.h"
78 #include "nsICSSLoader.h"
79 #include "nsICSSStyleSheet.h"
80 #include "nsIConsoleService.h"
81 #include "nsIDirectoryService.h"
82 #include "nsIDocument.h"
83 #include "nsIDOMDocument.h"
84 #include "nsIDocShell.h"
85 #include "nsIDocumentObserver.h"
86 #include "nsIDOMElement.h"
87 #include "nsIDOMLocation.h"
88 #include "nsIDOMWindowCollection.h"
89 #include "nsIDOMWindowInternal.h"
90 #include "nsIFileChannel.h"
91 #include "nsIFileURL.h"
92 #include "nsIIOService.h"
93 #include "nsIJARProtocolHandler.h"
94 #include "nsIJARURI.h"
95 #include "nsILocalFile.h"
96 #include "nsILocaleService.h"
97 #include "nsILookAndFeel.h"
98 #include "nsIObserverService.h"
99 #include "nsIPrefService.h"
100 #include "nsIPrefBranch.h"
101 #include "nsIPrefBranch2.h"
102 #include "nsIPresShell.h"
103 #include "nsIProtocolHandler.h"
104 #include "nsIResProtocolHandler.h"
105 #include "nsIScriptError.h"
106 #include "nsIServiceManager.h"
107 #include "nsISimpleEnumerator.h"
108 #include "nsIStyleSheet.h"
109 #include "nsISupportsArray.h"
110 #include "nsIVersionComparator.h"
111 #include "nsIWindowMediator.h"
112 #include "nsIXPConnect.h"
113 #include "nsIXULAppInfo.h"
114 #include "nsIXULRuntime.h"
115 #include "nsPresShellIterator.h"
118 // keep all the RDF stuff together, in case we can remove it in the far future
120 #include "nsRDFCID.h"
121 #include "nsIRDFService.h"
122 #include "nsIRDFDataSource.h"
123 #include "nsIRDFObserver.h"
124 #include "nsIRDFRemoteDataSource.h"
125 #include "nsIRDFXMLSink.h"
126 #include "nsIRDFResource.h"
127 #include "nsIRDFDataSource.h"
128 #include "nsIRDFContainer.h"
129 #include "nsIRDFContainerUtils.h"
131 #define CHROME_URI "http://www.mozilla.org/rdf/chrome#"
133 DEFINE_RDF_VOCAB(CHROME_URI
, CHROME
, packages
);
134 DEFINE_RDF_VOCAB(CHROME_URI
, CHROME
, package
);
135 DEFINE_RDF_VOCAB(CHROME_URI
, CHROME
, name
);
136 DEFINE_RDF_VOCAB(CHROME_URI
, CHROME
, platformPackage
);
140 #define UILOCALE_CMD_LINE_ARG "UILocale"
142 #define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
143 #define SELECTED_LOCALE_PREF "general.useragent.locale"
144 #define SELECTED_SKIN_PREF "general.skins.selectedSkin"
146 static NS_DEFINE_CID(kCSSLoaderCID
, NS_CSS_LOADER_CID
);
147 static NS_DEFINE_CID(kLookAndFeelCID
, NS_LOOKANDFEEL_CID
);
149 nsChromeRegistry
* nsChromeRegistry::gChromeRegistry
;
151 ////////////////////////////////////////////////////////////////////////////////
154 LogMessage(const char* aMsg
, ...)
156 nsCOMPtr
<nsIConsoleService
> console
157 (do_GetService(NS_CONSOLESERVICE_CONTRACTID
));
162 va_start(args
, aMsg
);
163 char* formatted
= PR_vsmprintf(aMsg
, args
);
168 console
->LogStringMessage(NS_ConvertUTF8toUTF16(formatted
).get());
169 PR_smprintf_free(formatted
);
173 LogMessageWithContext(nsIURI
* aURL
, PRUint32 aLineNumber
, PRUint32 flags
,
174 const char* aMsg
, ...)
178 nsCOMPtr
<nsIConsoleService
> console
179 (do_GetService(NS_CONSOLESERVICE_CONTRACTID
));
181 nsCOMPtr
<nsIScriptError
> error
182 (do_CreateInstance(NS_SCRIPTERROR_CONTRACTID
));
183 if (!console
|| !error
)
187 va_start(args
, aMsg
);
188 char* formatted
= PR_vsmprintf(aMsg
, args
);
197 rv
= error
->Init(NS_ConvertUTF8toUTF16(formatted
).get(),
198 NS_ConvertUTF8toUTF16(spec
).get(),
200 aLineNumber
, 0, flags
, "chrome registration");
201 PR_smprintf_free(formatted
);
206 console
->LogMessage(error
);
209 // We use a "best-fit" algorithm for matching locales and themes.
210 // 1) the exact selected locale/theme
211 // 2) (locales only) same language, different country
212 // e.g. en-GB is the selected locale, only en-US is available
213 // 3) any available locale/theme
216 * Match the language-part of two lang-COUNTRY codes, hopefully but
217 * not guaranteed to be in the form ab-CD or abz-CD. "ab" should also
218 * work, any other garbage-in will produce undefined results as long
219 * as it does not crash.
222 LanguagesMatch(const nsACString
& a
, const nsACString
& b
)
224 if (a
.Length() < 2 || b
.Length() < 2)
227 nsACString::const_iterator as
, ae
, bs
, be
;
240 if (as
== ae
&& bs
== be
)
255 nsChromeRegistry::ProviderEntry
*
256 nsChromeRegistry::nsProviderArray::GetProvider(const nsACString
& aPreferred
, MatchType aType
)
258 PRInt32 i
= mArray
.Count();
262 ProviderEntry
* found
= nsnull
; // Only set if we find a partial-match locale
263 ProviderEntry
* entry
;
266 entry
= reinterpret_cast<ProviderEntry
*>(mArray
[i
]);
267 if (aPreferred
.Equals(entry
->provider
))
273 if (LanguagesMatch(aPreferred
, entry
->provider
)) {
278 if (!found
&& entry
->provider
.EqualsLiteral("en-US"))
282 if (!found
&& aType
!= EXACT
)
289 nsChromeRegistry::nsProviderArray::GetBase(const nsACString
& aPreferred
, MatchType aType
)
291 ProviderEntry
* provider
= GetProvider(aPreferred
, aType
);
296 return provider
->baseURI
;
300 nsChromeRegistry::nsProviderArray::GetSelected(const nsACString
& aPreferred
, MatchType aType
)
302 ProviderEntry
* entry
= GetProvider(aPreferred
, aType
);
305 return entry
->provider
;
307 return EmptyCString();
311 nsChromeRegistry::nsProviderArray::SetBase(const nsACString
& aProvider
, nsIURI
* aBaseURL
)
313 ProviderEntry
* provider
= GetProvider(aProvider
, EXACT
);
316 provider
->baseURI
= aBaseURL
;
320 // no existing entries, add a new one
321 provider
= new ProviderEntry(aProvider
, aBaseURL
);
323 return; // It's safe to silently fail on OOM
325 mArray
.AppendElement(provider
);
329 nsChromeRegistry::nsProviderArray::EnumerateToArray(nsCStringArray
*a
)
331 PRInt32 i
= mArray
.Count();
333 ProviderEntry
*entry
= reinterpret_cast<ProviderEntry
*>(mArray
[i
]);
334 a
->AppendCString(entry
->provider
);
339 nsChromeRegistry::nsProviderArray::Clear()
341 PRInt32 i
= mArray
.Count();
343 ProviderEntry
* entry
= reinterpret_cast<ProviderEntry
*>(mArray
[i
]);
350 nsChromeRegistry::PackageEntry::PackageEntry(const nsACString
& aPackage
) :
351 package(aPackage
), flags(0)
356 nsChromeRegistry::HashKey(PLDHashTable
*table
, const void *key
)
358 const nsACString
& str
= *reinterpret_cast<const nsACString
*>(key
);
359 return HashString(str
);
363 nsChromeRegistry::MatchKey(PLDHashTable
*table
, const PLDHashEntryHdr
*entry
,
366 const nsACString
& str
= *reinterpret_cast<const nsACString
*>(key
);
367 const PackageEntry
* pentry
= static_cast<const PackageEntry
*>(entry
);
368 return str
.Equals(pentry
->package
);
372 nsChromeRegistry::ClearEntry(PLDHashTable
*table
, PLDHashEntryHdr
*entry
)
374 PackageEntry
* pentry
= static_cast<PackageEntry
*>(entry
);
375 pentry
->~PackageEntry();
379 nsChromeRegistry::InitEntry(PLDHashTable
*table
, PLDHashEntryHdr
*entry
,
382 const nsACString
& str
= *reinterpret_cast<const nsACString
*>(key
);
384 new (entry
) PackageEntry(str
);
388 const PLDHashTableOps
389 nsChromeRegistry::kTableOps
= {
394 PL_DHashMoveEntryStub
,
396 PL_DHashFinalizeStub
,
401 nsChromeRegistry::OverlayListEntry::AddURI(nsIURI
* aURI
)
403 PRInt32 i
= mArray
.Count();
406 if (NS_SUCCEEDED(aURI
->Equals(mArray
[i
], &equals
)) && equals
)
410 mArray
.AppendObject(aURI
);
414 nsChromeRegistry::OverlayListHash::Add(nsIURI
* aBase
, nsIURI
* aOverlay
)
416 OverlayListEntry
* entry
= mTable
.PutEntry(aBase
);
418 entry
->AddURI(aOverlay
);
421 const nsCOMArray
<nsIURI
>*
422 nsChromeRegistry::OverlayListHash::GetArray(nsIURI
* aBase
)
424 OverlayListEntry
* entry
= mTable
.GetEntry(aBase
);
428 return &entry
->mArray
;
431 nsChromeRegistry::~nsChromeRegistry()
433 if (mPackagesHash
.ops
)
434 PL_DHashTableFinish(&mPackagesHash
);
435 gChromeRegistry
= nsnull
;
438 NS_INTERFACE_MAP_BEGIN(nsChromeRegistry
)
439 NS_INTERFACE_MAP_ENTRY(nsIChromeRegistry
)
440 NS_INTERFACE_MAP_ENTRY(nsIXULChromeRegistry
)
441 NS_INTERFACE_MAP_ENTRY(nsIToolkitChromeRegistry
)
443 NS_INTERFACE_MAP_ENTRY(nsIXULOverlayProvider
)
445 NS_INTERFACE_MAP_ENTRY(nsIObserver
)
446 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference
)
447 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIChromeRegistry
)
450 NS_IMPL_ADDREF(nsChromeRegistry
)
451 NS_IMPL_RELEASE(nsChromeRegistry
)
453 ////////////////////////////////////////////////////////////////////////////////
454 // nsIChromeRegistry methods:
457 getUILangCountry(nsACString
& aUILang
)
461 nsCOMPtr
<nsILocaleService
> localeService
= do_GetService(NS_LOCALESERVICE_CONTRACTID
, &rv
);
462 NS_ENSURE_SUCCESS(rv
, rv
);
465 rv
= localeService
->GetLocaleComponentForUserAgent(uiLang
);
466 NS_ENSURE_SUCCESS(rv
, rv
);
468 CopyUTF16toUTF8(uiLang
, aUILang
);
473 nsChromeRegistry::Init()
477 // these atoms appear in almost every chrome registry contents.rdf
478 // in some form or another. making static atoms prevents the atoms
479 // from constantly being created/destroyed during parsing
481 static const nsStaticAtom atoms
[] = {
482 { "chrome", nsnull
},
484 { "allowScripts", nsnull
},
485 { "package", nsnull
},
486 { "packages", nsnull
},
487 { "hasOverlays", nsnull
},
490 NS_RegisterStaticAtoms(atoms
, NS_ARRAY_LENGTH(atoms
));
492 // Check to see if necko and the JAR protocol handler are registered yet
493 // if not, somebody is doing work during XPCOM registration that they
494 // shouldn't be doing. See bug 292549, where JS components are trying
495 // to call Components.utils.import("chrome:///") early in registration
497 nsCOMPtr
<nsIIOService
> io (do_GetIOService());
498 if (!io
) return NS_ERROR_FAILURE
;
500 nsCOMPtr
<nsIProtocolHandler
> ph
;
501 rv
= io
->GetProtocolHandler("jar", getter_AddRefs(ph
));
502 NS_ENSURE_SUCCESS(rv
, rv
);
504 nsCOMPtr
<nsIJARProtocolHandler
> jph
= do_QueryInterface(ph
);
506 return NS_ERROR_NOT_INITIALIZED
;
508 if (!PL_DHashTableInit(&mPackagesHash
, &kTableOps
,
509 nsnull
, sizeof(PackageEntry
), 16))
510 return NS_ERROR_FAILURE
;
512 if (!mOverlayHash
.Init() ||
513 !mStyleHash
.Init() ||
514 !mOverrideTable
.Init())
515 return NS_ERROR_FAILURE
;
517 mSelectedLocale
= NS_LITERAL_CSTRING("en-US");
518 mSelectedSkin
= NS_LITERAL_CSTRING("classic/1.0");
520 // This initialization process is fairly complicated and may cause reentrant
521 // getservice calls to resolve chrome URIs (especially locale files). We
522 // don't want that, so we inform the protocol handler about our existence
523 // before we are actually fully initialized.
524 gChromeRegistry
= this;
526 PRBool safeMode
= PR_FALSE
;
527 nsCOMPtr
<nsIXULRuntime
> xulrun (do_GetService(XULAPPINFO_SERVICE_CONTRACTID
));
529 xulrun
->GetInSafeMode(&safeMode
);
531 nsCOMPtr
<nsIPrefService
> prefserv (do_GetService(NS_PREFSERVICE_CONTRACTID
));
532 nsCOMPtr
<nsIPrefBranch
> prefs
;
535 prefserv
->GetDefaultBranch(nsnull
, getter_AddRefs(prefs
));
537 prefs
= do_QueryInterface(prefserv
);
540 NS_WARNING("Could not get pref service!");
543 PRBool useLocalePref
= PR_TRUE
;
546 // check the pref first
547 PRBool matchOS
= PR_FALSE
;
548 rv
= prefs
->GetBoolPref(MATCH_OS_LOCALE_PREF
, &matchOS
);
551 if (NS_SUCCEEDED(rv
) && matchOS
) {
552 // compute lang and region code only when needed!
553 nsCAutoString uiLocale
;
554 rv
= getUILangCountry(uiLocale
);
555 if (NS_SUCCEEDED(rv
)) {
556 useLocalePref
= PR_FALSE
;
557 mSelectedLocale
= uiLocale
;
563 nsXPIDLCString provider
;
565 rv
= prefs
->GetCharPref(SELECTED_SKIN_PREF
, getter_Copies(provider
));
566 if (NS_SUCCEEDED(rv
))
567 mSelectedSkin
= provider
;
569 nsCOMPtr
<nsIPrefBranch2
> prefs2 (do_QueryInterface(prefs
));
572 rv
= prefs2
->AddObserver(SELECTED_SKIN_PREF
, this, PR_TRUE
);
575 rv
= prefs
->GetCharPref(SELECTED_LOCALE_PREF
, getter_Copies(provider
));
576 if (NS_SUCCEEDED(rv
))
577 mSelectedLocale
= provider
;
580 prefs2
->AddObserver(SELECTED_LOCALE_PREF
, this, PR_TRUE
);
586 mInitialized
= PR_TRUE
;
592 nsChromeRegistry::CheckForOSAccessibility()
596 nsCOMPtr
<nsILookAndFeel
> lookAndFeel (do_GetService(kLookAndFeelCID
));
598 PRInt32 useAccessibilityTheme
= 0;
600 rv
= lookAndFeel
->GetMetric(nsILookAndFeel::eMetric_UseAccessibilityTheme
,
601 useAccessibilityTheme
);
603 if (NS_SUCCEEDED(rv
) && useAccessibilityTheme
) {
604 /* Set the skin to classic and remove pref observers */
605 if (!mSelectedSkin
.EqualsLiteral("classic/1.0")) {
606 mSelectedSkin
.AssignLiteral("classic/1.0");
610 nsCOMPtr
<nsIPrefBranch2
> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID
));
612 prefs
->RemoveObserver(SELECTED_SKIN_PREF
, this);
621 nsChromeRegistry::GetProviderAndPath(nsIURL
* aChromeURL
,
622 nsACString
& aProvider
, nsACString
& aPath
)
628 aChromeURL
->SchemeIs("chrome", &isChrome
);
629 NS_ASSERTION(isChrome
, "Non-chrome URI?");
633 rv
= aChromeURL
->GetPath(path
);
634 NS_ENSURE_SUCCESS(rv
, rv
);
636 if (path
.Length() < 3) {
637 LogMessage("Invalid chrome URI: %s", path
.get());
638 return NS_ERROR_FAILURE
;
641 path
.SetLength(nsUnescapeCount(path
.BeginWriting()));
642 NS_ASSERTION(path
.First() == '/', "Path should always begin with a slash!");
644 PRInt32 slash
= path
.FindChar('/', 1);
646 LogMessage("Invalid chrome URI: %s", path
.get());
647 return NS_ERROR_FAILURE
;
654 if (slash
== (PRInt32
) path
.Length() - 1)
657 aPath
.Assign(path
.get() + slash
+ 1, path
.Length() - slash
- 1);
662 aProvider
.Assign(path
.get() + 1, slash
);
668 nsChromeRegistry::Canonify(nsIURL
* aChromeURL
)
670 NS_NAMED_LITERAL_CSTRING(kSlash
, "/");
674 nsCAutoString provider
, path
;
675 rv
= GetProviderAndPath(aChromeURL
, provider
, path
);
676 NS_ENSURE_SUCCESS(rv
, rv
);
678 if (path
.IsEmpty()) {
679 nsCAutoString package
;
680 rv
= aChromeURL
->GetHost(package
);
681 NS_ENSURE_SUCCESS(rv
, rv
);
683 // we re-use the "path" local string to build a new URL path
684 path
.Assign(kSlash
+ provider
+ kSlash
+ package
);
685 if (provider
.EqualsLiteral("content")) {
686 path
.AppendLiteral(".xul");
688 else if (provider
.EqualsLiteral("locale")) {
689 path
.AppendLiteral(".dtd");
691 else if (provider
.EqualsLiteral("skin")) {
692 path
.AppendLiteral(".css");
695 return NS_ERROR_INVALID_ARG
;
697 aChromeURL
->SetPath(path
);
700 // prevent directory traversals ("..")
701 // path is already unescaped once, but uris can get unescaped twice
702 const char* pos
= path
.BeginReading();
703 const char* end
= path
.EndReading();
707 return NS_ERROR_DOM_BAD_URI
;
710 return NS_ERROR_DOM_BAD_URI
;
713 // chrome: URIs with double-escapes are trying to trick us.
714 // watch for %2e, and %25 in case someone triple unescapes
716 ( pos
[2] == 'e' || pos
[2] == 'E' ||
718 return NS_ERROR_DOM_BAD_URI
;
733 nsChromeRegistry::ConvertChromeURL(nsIURI
* aChromeURI
, nsIURI
* *aResult
)
736 NS_ASSERTION(aChromeURI
, "null url!");
738 if (mOverrideTable
.Get(aChromeURI
, aResult
))
741 nsCOMPtr
<nsIURL
> chromeURL (do_QueryInterface(aChromeURI
));
742 NS_ENSURE_TRUE(chromeURL
, NS_NOINTERFACE
);
744 nsCAutoString package
, provider
, path
;
745 rv
= chromeURL
->GetHostPort(package
);
746 NS_ENSURE_SUCCESS(rv
, rv
);
748 rv
= GetProviderAndPath(chromeURL
, provider
, path
);
749 NS_ENSURE_SUCCESS(rv
, rv
);
751 PackageEntry
* entry
=
752 static_cast<PackageEntry
*>(PL_DHashTableOperate(&mPackagesHash
,
753 & (nsACString
&) package
,
756 if (PL_DHASH_ENTRY_IS_FREE(entry
)) {
758 return NS_ERROR_NOT_INITIALIZED
;
760 LogMessage("No chrome package registered for chrome://%s/%s/%s",
761 package
.get(), provider
.get(), path
.get());
763 return NS_ERROR_FAILURE
;
766 if (entry
->flags
& PackageEntry::PLATFORM_PACKAGE
) {
767 #if defined(XP_WIN) || defined(XP_OS2)
768 path
.Insert("win/", 0);
769 #elif defined(XP_MACOSX)
770 path
.Insert("mac/", 0);
772 path
.Insert("unix/", 0);
776 nsIURI
* baseURI
= nsnull
;
777 if (provider
.EqualsLiteral("locale")) {
778 baseURI
= entry
->locales
.GetBase(mSelectedLocale
, nsProviderArray::LOCALE
);
780 else if (provider
.EqualsLiteral("skin")) {
781 baseURI
= entry
->skins
.GetBase(mSelectedSkin
, nsProviderArray::ANY
);
783 else if (provider
.EqualsLiteral("content")) {
784 baseURI
= entry
->baseURI
;
788 LogMessage("No chrome package registered for chrome://%s/%s/%s",
789 package
.get(), provider
.get(), path
.get());
790 return NS_ERROR_FAILURE
;
793 return NS_NewURI(aResult
, path
, nsnull
, baseURI
);
797 nsChromeRegistry::GetSelectedLocale(const nsACString
& aPackage
, nsACString
& aLocale
)
799 PackageEntry
* entry
=
800 static_cast<PackageEntry
*>(PL_DHashTableOperate(&mPackagesHash
,
804 if (PL_DHASH_ENTRY_IS_FREE(entry
))
805 return NS_ERROR_FAILURE
;
807 aLocale
= entry
->locales
.GetSelected(mSelectedLocale
, nsProviderArray::LOCALE
);
808 if (aLocale
.IsEmpty())
809 return NS_ERROR_FAILURE
;
815 nsChromeRegistry::GetLocalesForPackage(const nsACString
& aPackage
,
816 nsIUTF8StringEnumerator
* *aResult
)
818 nsCStringArray
*a
= new nsCStringArray
;
820 return NS_ERROR_OUT_OF_MEMORY
;
822 PackageEntry
* entry
=
823 static_cast<PackageEntry
*>(PL_DHashTableOperate(&mPackagesHash
,
827 if (PL_DHASH_ENTRY_IS_BUSY(entry
)) {
828 entry
->locales
.EnumerateToArray(a
);
831 nsresult rv
= NS_NewAdoptingUTF8StringEnumerator(aResult
, a
);
840 nsChromeRegistry::GetStyleOverlays(nsIURI
*aChromeURL
,
841 nsISimpleEnumerator
**aResult
)
843 const nsCOMArray
<nsIURI
>* parray
= mStyleHash
.GetArray(aChromeURL
);
845 return NS_NewEmptyEnumerator(aResult
);
847 return NS_NewArrayEnumerator(aResult
, *parray
);
851 nsChromeRegistry::GetXULOverlays(nsIURI
*aChromeURL
, nsISimpleEnumerator
**aResult
)
853 const nsCOMArray
<nsIURI
>* parray
= mOverlayHash
.GetArray(aChromeURL
);
855 return NS_NewEmptyEnumerator(aResult
);
857 return NS_NewArrayEnumerator(aResult
, *parray
);
861 ////////////////////////////////////////////////////////////////////////
866 static void FlushSkinBindingsForWindow(nsIDOMWindowInternal
* aWindow
)
868 // Get the DOM document.
869 nsCOMPtr
<nsIDOMDocument
> domDocument
;
870 aWindow
->GetDocument(getter_AddRefs(domDocument
));
874 nsCOMPtr
<nsIDocument
> document
= do_QueryInterface(domDocument
);
878 // Annihilate all XBL bindings.
879 document
->FlushSkinBindings();
882 // XXXbsmedberg: move this to nsIWindowMediator
883 NS_IMETHODIMP
nsChromeRegistry::RefreshSkins()
885 nsCOMPtr
<nsICSSLoader
> cssLoader(do_CreateInstance(kCSSLoaderCID
));
889 nsCOMPtr
<nsIWindowMediator
> windowMediator
890 (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID
));
894 nsCOMPtr
<nsISimpleEnumerator
> windowEnumerator
;
895 windowMediator
->GetEnumerator(nsnull
, getter_AddRefs(windowEnumerator
));
897 windowEnumerator
->HasMoreElements(&more
);
899 nsCOMPtr
<nsISupports
> protoWindow
;
900 windowEnumerator
->GetNext(getter_AddRefs(protoWindow
));
902 nsCOMPtr
<nsIDOMWindowInternal
> domWindow
= do_QueryInterface(protoWindow
);
904 FlushSkinBindingsForWindow(domWindow
);
906 windowEnumerator
->HasMoreElements(&more
);
911 windowMediator
->GetEnumerator(nsnull
, getter_AddRefs(windowEnumerator
));
912 windowEnumerator
->HasMoreElements(&more
);
914 nsCOMPtr
<nsISupports
> protoWindow
;
915 windowEnumerator
->GetNext(getter_AddRefs(protoWindow
));
917 nsCOMPtr
<nsIDOMWindowInternal
> domWindow
= do_QueryInterface(protoWindow
);
919 RefreshWindow(domWindow
, cssLoader
);
921 windowEnumerator
->HasMoreElements(&more
);
928 nsChromeRegistry::FlushSkinCaches()
930 nsCOMPtr
<nsIObserverService
> obsSvc
=
931 do_GetService("@mozilla.org/observer-service;1");
932 NS_ASSERTION(obsSvc
, "Couldn't get observer service.");
934 obsSvc
->NotifyObservers(static_cast<nsIChromeRegistry
*>(this),
935 NS_CHROME_FLUSH_SKINS_TOPIC
, nsnull
);
938 static PRBool
IsChromeURI(nsIURI
* aURI
)
940 PRBool isChrome
=PR_FALSE
;
941 if (NS_SUCCEEDED(aURI
->SchemeIs("chrome", &isChrome
)) && isChrome
)
946 // XXXbsmedberg: move this to windowmediator
947 nsresult
nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal
* aWindow
,
948 nsICSSLoader
* aCSSLoader
)
950 // Deal with our subframes first.
951 nsCOMPtr
<nsIDOMWindowCollection
> frames
;
952 aWindow
->GetFrames(getter_AddRefs(frames
));
954 frames
->GetLength(&length
);
956 for (j
= 0; j
< length
; j
++) {
957 nsCOMPtr
<nsIDOMWindow
> childWin
;
958 frames
->Item(j
, getter_AddRefs(childWin
));
959 nsCOMPtr
<nsIDOMWindowInternal
> childInt(do_QueryInterface(childWin
));
960 RefreshWindow(childInt
, aCSSLoader
);
964 // Get the DOM document.
965 nsCOMPtr
<nsIDOMDocument
> domDocument
;
966 aWindow
->GetDocument(getter_AddRefs(domDocument
));
970 nsCOMPtr
<nsIDocument
> document
= do_QueryInterface(domDocument
);
974 // Deal with the agent sheets first. Have to do all the style sets by hand.
975 nsPresShellIterator
iter(document
);
976 nsCOMPtr
<nsIPresShell
> shell
;
977 while ((shell
= iter
.GetNextShell())) {
978 // Reload only the chrome URL agent style sheets.
979 nsCOMArray
<nsIStyleSheet
> agentSheets
;
980 rv
= shell
->GetAgentStyleSheets(agentSheets
);
981 NS_ENSURE_SUCCESS(rv
, rv
);
983 nsCOMArray
<nsIStyleSheet
> newAgentSheets
;
984 for (PRInt32 l
= 0; l
< agentSheets
.Count(); ++l
) {
985 nsIStyleSheet
*sheet
= agentSheets
[l
];
987 nsCOMPtr
<nsIURI
> uri
;
988 rv
= sheet
->GetSheetURI(getter_AddRefs(uri
));
989 if (NS_FAILED(rv
)) return rv
;
991 if (IsChromeURI(uri
)) {
993 nsCOMPtr
<nsICSSStyleSheet
> newSheet
;
994 rv
= aCSSLoader
->LoadSheetSync(uri
, PR_TRUE
, getter_AddRefs(newSheet
));
995 if (NS_FAILED(rv
)) return rv
;
997 rv
= newAgentSheets
.AppendObject(newSheet
) ? NS_OK
: NS_ERROR_FAILURE
;
998 if (NS_FAILED(rv
)) return rv
;
1001 else { // Just use the same sheet.
1002 rv
= newAgentSheets
.AppendObject(sheet
) ? NS_OK
: NS_ERROR_FAILURE
;
1003 if (NS_FAILED(rv
)) return rv
;
1007 rv
= shell
->SetAgentStyleSheets(newAgentSheets
);
1008 NS_ENSURE_SUCCESS(rv
, rv
);
1011 // Build an array of nsIURIs of style sheets we need to load.
1012 nsCOMArray
<nsIStyleSheet
> oldSheets
;
1013 nsCOMArray
<nsIStyleSheet
> newSheets
;
1015 PRInt32 count
= document
->GetNumberOfStyleSheets();
1017 // Iterate over the style sheets.
1019 for (i
= 0; i
< count
; i
++) {
1020 // Get the style sheet
1021 nsIStyleSheet
*styleSheet
= document
->GetStyleSheetAt(i
);
1023 if (!oldSheets
.AppendObject(styleSheet
)) {
1024 return NS_ERROR_OUT_OF_MEMORY
;
1028 // Iterate over our old sheets and kick off a sync load of the new
1029 // sheet if and only if it's a chrome URL.
1030 for (i
= 0; i
< count
; i
++) {
1031 nsCOMPtr
<nsIStyleSheet
> sheet
= oldSheets
[i
];
1032 nsCOMPtr
<nsIURI
> uri
;
1033 rv
= sheet
->GetSheetURI(getter_AddRefs(uri
));
1034 if (NS_FAILED(rv
)) return rv
;
1036 if (IsChromeURI(uri
)) {
1037 // Reload the sheet.
1039 nsCOMPtr
<nsICSSStyleSheet
> oldCSSSheet
= do_QueryInterface(sheet
);
1040 NS_ASSERTION(oldCSSSheet
, "Don't know how to reload a non-CSS sheet");
1042 nsCOMPtr
<nsICSSStyleSheet
> newSheet
;
1043 // XXX what about chrome sheets that have a title or are disabled? This
1044 // only works by sheer dumb luck.
1045 // XXXbz this should really use the document's CSSLoader!
1046 aCSSLoader
->LoadSheetSync(uri
, getter_AddRefs(newSheet
));
1047 // Even if it's null, we put in in there.
1048 newSheets
.AppendObject(newSheet
);
1051 // Just use the same sheet.
1052 newSheets
.AppendObject(sheet
);
1056 // Now notify the document that multiple sheets have been added and removed.
1057 document
->UpdateStyleSheets(oldSheets
, newSheets
);
1062 nsChromeRegistry::FlushAllCaches()
1064 nsCOMPtr
<nsIObserverService
> obsSvc
=
1065 do_GetService("@mozilla.org/observer-service;1");
1066 NS_ASSERTION(obsSvc
, "Couldn't get observer service.");
1068 obsSvc
->NotifyObservers((nsIChromeRegistry
*) this,
1069 NS_CHROME_FLUSH_TOPIC
, nsnull
);
1072 // xxxbsmedberg Move me to nsIWindowMediator
1074 nsChromeRegistry::ReloadChrome()
1077 // Do a reload of all top level windows.
1078 nsresult rv
= NS_OK
;
1080 // Get the window mediator
1081 nsCOMPtr
<nsIWindowMediator
> windowMediator
1082 (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID
));
1083 if (windowMediator
) {
1084 nsCOMPtr
<nsISimpleEnumerator
> windowEnumerator
;
1086 rv
= windowMediator
->GetEnumerator(nsnull
, getter_AddRefs(windowEnumerator
));
1087 if (NS_SUCCEEDED(rv
)) {
1088 // Get each dom window
1090 rv
= windowEnumerator
->HasMoreElements(&more
);
1091 if (NS_FAILED(rv
)) return rv
;
1093 nsCOMPtr
<nsISupports
> protoWindow
;
1094 rv
= windowEnumerator
->GetNext(getter_AddRefs(protoWindow
));
1095 if (NS_SUCCEEDED(rv
)) {
1096 nsCOMPtr
<nsIDOMWindowInternal
> domWindow
=
1097 do_QueryInterface(protoWindow
);
1099 nsCOMPtr
<nsIDOMLocation
> location
;
1100 domWindow
->GetLocation(getter_AddRefs(location
));
1102 rv
= location
->Reload(PR_FALSE
);
1103 if (NS_FAILED(rv
)) return rv
;
1107 rv
= windowEnumerator
->HasMoreElements(&more
);
1108 if (NS_FAILED(rv
)) return rv
;
1116 nsChromeRegistry::AllowScriptsForPackage(nsIURI
* aChromeURI
, PRBool
*aResult
)
1119 *aResult
= PR_FALSE
;
1123 aChromeURI
->SchemeIs("chrome", &isChrome
);
1124 NS_ASSERTION(isChrome
, "Non-chrome URI passed to AllowScriptsForPackage!");
1127 nsCOMPtr
<nsIURL
> url (do_QueryInterface(aChromeURI
));
1128 NS_ENSURE_TRUE(url
, NS_NOINTERFACE
);
1130 nsCAutoString provider
, file
;
1131 rv
= GetProviderAndPath(url
, provider
, file
);
1132 NS_ENSURE_SUCCESS(rv
, rv
);
1134 if (!provider
.EqualsLiteral("skin"))
1141 nsChromeRegistry::AllowContentToAccess(nsIURI
*aURI
, PRBool
*aResult
)
1145 *aResult
= PR_FALSE
;
1149 aURI
->SchemeIs("chrome", &isChrome
);
1150 NS_ASSERTION(isChrome
, "Non-chrome URI passed to AllowContentToAccess!");
1153 nsCOMPtr
<nsIURL
> url
= do_QueryInterface(aURI
);
1155 NS_ERROR("Chrome URL doesn't implement nsIURL.");
1156 return NS_ERROR_UNEXPECTED
;
1159 nsCAutoString package
;
1160 rv
= url
->GetHostPort(package
);
1161 NS_ENSURE_SUCCESS(rv
, rv
);
1163 PackageEntry
*entry
=
1164 static_cast<PackageEntry
*>(PL_DHashTableOperate(&mPackagesHash
,
1165 & (nsACString
&) package
,
1168 if (PL_DHASH_ENTRY_IS_BUSY(entry
)) {
1169 *aResult
= !!(entry
->flags
& PackageEntry::CONTENT_ACCESSIBLE
);
1174 static PLDHashOperator
1175 RemoveAll(PLDHashTable
*table
, PLDHashEntryHdr
*entry
, PRUint32 number
, void *arg
)
1177 return (PLDHashOperator
) (PL_DHASH_NEXT
| PL_DHASH_REMOVE
);
1181 nsChromeRegistry::CheckForNewChrome()
1185 PL_DHashTableEnumerate(&mPackagesHash
, RemoveAll
, nsnull
);
1186 mOverlayHash
.Clear();
1188 mOverrideTable
.Clear();
1190 nsCOMPtr
<nsIURI
> manifestURI
;
1191 rv
= NS_NewURI(getter_AddRefs(manifestURI
),
1192 NS_LITERAL_CSTRING("resource:///chrome/app-chrome.manifest"));
1194 // this is the main manifest; if it doesn't exist we generate it from
1195 // installed-chrome.txt. When the build system learns about the new system,
1196 // this code can go away.
1198 nsCOMPtr
<nsIFileURL
> manifestFileURL (do_QueryInterface(manifestURI
));
1199 NS_ASSERTION(manifestFileURL
, "Not a nsIFileURL!");
1200 NS_ENSURE_TRUE(manifestFileURL
, NS_ERROR_UNEXPECTED
);
1202 nsCOMPtr
<nsIFile
> manifest
;
1203 manifestFileURL
->GetFile(getter_AddRefs(manifest
));
1204 NS_ENSURE_TRUE(manifest
, NS_ERROR_FAILURE
);
1207 rv
= manifest
->Exists(&exists
);
1208 NS_ENSURE_SUCCESS(rv
, rv
);
1211 // In debug builds, installed-chrome.txt may change during development;
1212 // we just rebuild it every time because we're not worried about startup
1213 // time or other bad/goodness.
1215 manifest
->Remove(PR_FALSE
);
1221 nsCOMPtr
<nsIFile
> installed
;
1222 manifest
->Clone(getter_AddRefs(installed
));
1224 return NS_ERROR_OUT_OF_MEMORY
;
1226 nsCOMPtr
<nsILocalFile
> linstalled (do_QueryInterface(installed
));
1227 NS_ENSURE_TRUE(linstalled
, NS_NOINTERFACE
);
1229 linstalled
->SetNativeLeafName(NS_LITERAL_CSTRING("installed-chrome.txt"));
1231 rv
= linstalled
->Exists(&exists
);
1232 NS_ENSURE_SUCCESS(rv
, rv
);
1234 // process installed-chrome.txt into app-chrome.manifest
1236 ProcessNewChromeFile(linstalled
, manifestURI
);
1239 nsCOMPtr
<nsIProperties
> dirSvc (do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID
));
1240 NS_ENSURE_TRUE(dirSvc
, NS_ERROR_FAILURE
);
1242 // check the extra chrome directories
1243 nsCOMPtr
<nsISimpleEnumerator
> chromeML
;
1244 rv
= dirSvc
->Get(NS_CHROME_MANIFESTS_FILE_LIST
, NS_GET_IID(nsISimpleEnumerator
),
1245 getter_AddRefs(chromeML
));
1246 if (NS_FAILED(rv
)) {
1247 // ok, then simply load all .manifest files in the app chrome dir.
1248 nsCOMPtr
<nsIFile
> chromeDir
;
1249 rv
= dirSvc
->Get(NS_APP_CHROME_DIR
, NS_GET_IID(nsIFile
),
1250 getter_AddRefs(chromeDir
));
1253 rv
= NS_NewSingletonEnumerator(getter_AddRefs(chromeML
), chromeDir
);
1258 nsCOMPtr
<nsISupports
> next
;
1259 while (NS_SUCCEEDED(chromeML
->HasMoreElements(&exists
)) && exists
) {
1260 chromeML
->GetNext(getter_AddRefs(next
));
1261 nsCOMPtr
<nsILocalFile
> lmanifest
= do_QueryInterface(next
);
1263 NS_ERROR("Directory enumerator returned a non-nsILocalFile");
1268 if (NS_SUCCEEDED(lmanifest
->IsDirectory(&isDir
)) && isDir
) {
1269 nsCOMPtr
<nsISimpleEnumerator
> entries
;
1270 rv
= lmanifest
->GetDirectoryEntries(getter_AddRefs(entries
));
1274 while (NS_SUCCEEDED(entries
->HasMoreElements(&exists
)) && exists
) {
1275 entries
->GetNext(getter_AddRefs(next
));
1276 lmanifest
= do_QueryInterface(next
);
1278 nsCAutoString leafName
;
1279 lmanifest
->GetNativeLeafName(leafName
);
1280 if (StringEndsWith(leafName
, NS_LITERAL_CSTRING(".manifest"))) {
1281 rv
= ProcessManifest(lmanifest
, PR_FALSE
);
1282 if (NS_FAILED(rv
)) {
1284 lmanifest
->GetNativePath(path
);
1285 LogMessage("Failed to process chrome manifest '%s'.",
1294 rv
= ProcessManifest(lmanifest
, PR_FALSE
);
1295 if (NS_FAILED(rv
)) {
1297 lmanifest
->GetNativePath(path
);
1298 LogMessage("Failed to process chrome manifest: '%s'.",
1304 rv
= dirSvc
->Get(NS_SKIN_MANIFESTS_FILE_LIST
, NS_GET_IID(nsISimpleEnumerator
),
1305 getter_AddRefs(chromeML
));
1309 while (NS_SUCCEEDED(chromeML
->HasMoreElements(&exists
)) && exists
) {
1310 chromeML
->GetNext(getter_AddRefs(next
));
1311 nsCOMPtr
<nsILocalFile
> lmanifest
= do_QueryInterface(next
);
1313 NS_ERROR("Directory enumerator returned a non-nsILocalFile");
1317 rv
= ProcessManifest(lmanifest
, PR_TRUE
);
1318 if (NS_FAILED(rv
)) {
1320 lmanifest
->GetNativePath(path
);
1321 LogMessage("Failed to process chrome manifest: '%s'.",
1330 nsChromeRegistry::ProcessNewChromeFile(nsILocalFile
*aListFile
, nsIURI
* aManifest
)
1335 rv
= aListFile
->OpenNSPRFileDesc(PR_RDONLY
, 0, &file
);
1336 NS_ENSURE_SUCCESS(rv
, rv
);
1341 size
= PR_Available(file
);
1343 rv
= NS_ERROR_UNEXPECTED
;
1347 buf
= (char *) malloc(size
+ 1);
1349 rv
= NS_ERROR_OUT_OF_MEMORY
;
1353 n
= PR_Read(file
, buf
, size
);
1355 rv
= ProcessNewChromeBuffer(buf
, size
, aManifest
);
1364 nsChromeRegistry::ProcessNewChromeBuffer(char *aBuffer
, PRInt32 aLength
,
1367 nsresult rv
= NS_OK
;
1368 char *bufferEnd
= aBuffer
+ aLength
;
1369 char *chromeType
, // "content", "locale" or "skin"
1370 *chromeProfile
, // "install" or "profile"
1371 *chromeLocType
, // type of location (local path or URL)
1372 *chromeLocation
; // base location of chrome (jar file)
1374 nsCOMPtr
<nsIURI
> baseURI
;
1376 // process chromeType, chromeProfile, chromeLocType, chromeLocation
1377 while (aBuffer
< bufferEnd
) {
1378 // parse one line of installed-chrome.txt
1379 chromeType
= aBuffer
;
1380 while (aBuffer
< bufferEnd
&& *aBuffer
!= ',')
1384 chromeProfile
= ++aBuffer
;
1385 if (aBuffer
>= bufferEnd
)
1388 while (aBuffer
< bufferEnd
&& *aBuffer
!= ',')
1392 chromeLocType
= ++aBuffer
;
1393 if (aBuffer
>= bufferEnd
)
1396 while (aBuffer
< bufferEnd
&& *aBuffer
!= ',')
1400 chromeLocation
= ++aBuffer
;
1401 if (aBuffer
>= bufferEnd
)
1404 while (aBuffer
< bufferEnd
&&
1405 (*aBuffer
!= '\r' && *aBuffer
!= '\n' && *aBuffer
!= ' '))
1410 // We don't do skin or locale selection from installed-chrome.txt since
1411 // ffox 0.9. Just ignore the "select" lines.
1412 if (strcmp(chromeLocType
,"select")) {
1413 if (!strcmp(chromeLocType
, "path")) {
1414 // location is a (full) path. convert it to an URL.
1416 /* this is some convoluted shit... this creates a file, inits it with
1417 * the path parsed above (chromeLocation), makes a url, and inits it
1418 * with the file created. the purpose of this is just to have the
1419 * canonical url of the stupid thing.
1421 nsCOMPtr
<nsILocalFile
> chromeFile
;
1422 rv
= NS_NewNativeLocalFile(nsDependentCString(chromeLocation
),
1423 PR_TRUE
, getter_AddRefs(chromeFile
));
1424 NS_ENSURE_SUCCESS(rv
, rv
);
1427 * all we want here is the canonical url
1429 rv
= NS_NewFileURI(getter_AddRefs(baseURI
), chromeFile
);
1430 if (NS_FAILED(rv
)) return rv
;
1433 rv
= NS_NewURI(getter_AddRefs(baseURI
), chromeLocation
);
1434 if (NS_FAILED(rv
)) return rv
;
1437 ProcessContentsManifest(baseURI
, aManifest
, baseURI
, PR_TRUE
,
1438 strcmp(chromeType
, "skin") == 0);
1441 while (aBuffer
< bufferEnd
&& (*aBuffer
== '\0' || *aBuffer
== ' ' || *aBuffer
== '\r' || *aBuffer
== '\n'))
1448 NS_IMETHODIMP
nsChromeRegistry::Observe(nsISupports
*aSubject
, const char *aTopic
, const PRUnichar
*someData
)
1450 nsresult rv
= NS_OK
;
1452 if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID
, aTopic
)) {
1453 nsCOMPtr
<nsIPrefBranch
> prefs (do_QueryInterface(aSubject
));
1454 NS_ASSERTION(prefs
, "Bad observer call!");
1456 NS_ConvertUTF16toUTF8
pref(someData
);
1458 nsXPIDLCString provider
;
1459 rv
= prefs
->GetCharPref(pref
.get(), getter_Copies(provider
));
1460 if (NS_FAILED(rv
)) {
1461 NS_ERROR("Couldn't get new locale or skin pref!");
1465 if (pref
.EqualsLiteral(SELECTED_SKIN_PREF
)) {
1466 mSelectedSkin
= provider
;
1469 else if (pref
.EqualsLiteral(SELECTED_LOCALE_PREF
)) {
1470 mSelectedLocale
= provider
;
1473 NS_ERROR("Unexpected pref!");
1476 else if (!strcmp("command-line-startup", aTopic
)) {
1477 nsCOMPtr
<nsICommandLine
> cmdLine (do_QueryInterface(aSubject
));
1479 nsAutoString uiLocale
;
1480 rv
= cmdLine
->HandleFlagWithParam(NS_LITERAL_STRING(UILOCALE_CMD_LINE_ARG
),
1481 PR_FALSE
, uiLocale
);
1482 if (NS_SUCCEEDED(rv
) && !uiLocale
.IsEmpty()) {
1483 CopyUTF16toUTF8(uiLocale
, mSelectedLocale
);
1484 nsCOMPtr
<nsIPrefBranch2
> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID
));
1486 prefs
->RemoveObserver(SELECTED_LOCALE_PREF
, this);
1492 NS_ERROR("Unexpected observer topic!");
1500 GetContainerEnumerator(nsIRDFDataSource
* ds
, nsIRDFResource
* res
,
1501 nsISimpleEnumerator
* *aResult
, PRInt32
*aCountResult
= nsnull
)
1505 nsCOMPtr
<nsIRDFContainer
> container
1506 (do_CreateInstance("@mozilla.org/rdf/container;1"));
1507 NS_ENSURE_TRUE(container
, NS_ERROR_FAILURE
);
1509 rv
= container
->Init(ds
, res
);
1510 if (NS_FAILED(rv
)) return rv
;
1513 container
->GetCount(aCountResult
);
1515 return container
->GetElements(aResult
);
1519 FollowLiteral(nsIRDFDataSource
* ds
, nsIRDFResource
* res
,
1520 nsIRDFResource
* arc
, nsACString
& result
)
1524 nsCOMPtr
<nsIRDFNode
> node
;
1525 rv
= ds
->GetTarget(res
, arc
, PR_TRUE
, getter_AddRefs(node
));
1526 if (NS_FAILED(rv
) || !node
) {
1531 nsCOMPtr
<nsIRDFLiteral
> literal (do_QueryInterface(node
));
1533 NS_ERROR("Arc found, but doesn't point to expected literal!");
1538 const PRUnichar
* value
;
1539 literal
->GetValueConst(&value
);
1540 CopyUTF16toUTF8(value
, result
);
1544 FollowResource(nsIRDFDataSource
* ds
, nsIRDFResource
* res
, nsIRDFResource
* arc
,
1545 nsIRDFResource
* *result
)
1549 nsCOMPtr
<nsIRDFNode
> node
;
1550 rv
= ds
->GetTarget(res
, arc
, PR_TRUE
, getter_AddRefs(node
));
1551 if (NS_FAILED(rv
) || !node
) {
1556 CallQueryInterface(node
, result
);
1560 GetRelativePath(nsIURI
* base
, nsIURI
* relative
, nsACString
& result
)
1564 nsCOMPtr
<nsIJARURI
> jarrelative (do_QueryInterface(relative
));
1566 nsCOMPtr
<nsIURI
> jarbase
;
1567 jarrelative
->GetJARFile(getter_AddRefs(jarbase
));
1569 nsCAutoString relativeBase
;
1570 GetRelativePath(base
, jarbase
, relativeBase
);
1572 nsCAutoString jarEntry
;
1573 jarrelative
->GetJAREntry(jarEntry
);
1575 result
.Assign(NS_LITERAL_CSTRING("jar:"));
1576 result
.Append(relativeBase
);
1577 result
.Append(NS_LITERAL_CSTRING("!/"));
1578 result
.Append(jarEntry
);
1582 nsCOMPtr
<nsIURL
> baseURL (do_QueryInterface(base
));
1584 relative
->GetSpec(result
);
1588 rv
= baseURL
->GetRelativeSpec(relative
, result
);
1589 if (NS_FAILED(rv
)) {
1590 relative
->GetSpec(result
);
1594 static const PRInt32 kNSPR_APPEND_FLAGS
= PR_WRONLY
| PR_CREATE_FILE
| PR_APPEND
;
1595 static const PRInt32 kNSPR_TRUNCATE_FLAGS
= PR_WRONLY
| PR_CREATE_FILE
| PR_TRUNCATE
;
1598 nsChromeRegistry::ProcessContentsManifest(nsIURI
* aOldManifest
, nsIURI
* aFile
,
1599 nsIURI
* aBaseURI
, PRBool aAppend
,
1604 nsCAutoString relativePath
;
1605 GetRelativePath(aFile
, aBaseURI
, relativePath
);
1608 aOldManifest
->GetSpec(spec
);
1610 NS_ASSERTION(spec
.Last() == '/', "installed-chrome manifest URI doesn't end in a slash! It probably won't work.");
1612 spec
.AppendLiteral("contents.rdf");
1614 nsCOMPtr
<nsIRDFService
> rdfs (do_GetService("@mozilla.org/rdf/rdf-service;1"));
1615 NS_ENSURE_TRUE(rdfs
, NS_ERROR_FAILURE
);
1617 nsCOMPtr
<nsIRDFResource
> namearc
, platformarc
;
1618 rdfs
->GetResource(NS_LITERAL_CSTRING(kURICHROME_name
),
1619 getter_AddRefs(namearc
));
1620 rdfs
->GetResource(NS_LITERAL_CSTRING(kURICHROME_platformPackage
),
1621 getter_AddRefs(platformarc
));
1622 if (!(namearc
&& platformarc
))
1623 return NS_ERROR_FAILURE
;
1625 nsCOMPtr
<nsIRDFDataSource
> ds
;
1626 rv
= rdfs
->GetDataSourceBlocking(spec
.get(), getter_AddRefs(ds
));
1627 if (NS_FAILED(rv
)) {
1628 LogMessage("Failed to load old-style contents.rdf at '%s'.",
1633 nsCOMPtr
<nsIFileURL
> fileURL (do_QueryInterface(aFile
));
1634 NS_ENSURE_TRUE(fileURL
, NS_ERROR_INVALID_ARG
);
1636 nsCOMPtr
<nsIFile
> file
;
1637 rv
= fileURL
->GetFile(getter_AddRefs(file
));
1638 NS_ENSURE_SUCCESS(rv
, rv
);
1640 nsCOMPtr
<nsILocalFile
> lfile (do_QueryInterface(file
));
1641 NS_ENSURE_TRUE(lfile
, NS_ERROR_NO_INTERFACE
);
1644 rv
= lfile
->OpenNSPRFileDesc(aAppend
? kNSPR_APPEND_FLAGS
: kNSPR_TRUNCATE_FLAGS
,
1646 NS_ENSURE_SUCCESS(rv
, rv
);
1649 PR_Write(fd
, "\n", 1);
1651 nsCOMPtr
<nsIRDFResource
> root
;
1652 rv
= rdfs
->GetResource(NS_LITERAL_CSTRING("urn:mozilla:skin:root"),
1653 getter_AddRefs(root
));
1654 if (NS_SUCCEEDED(rv
))
1655 ProcessProvider(fd
, rdfs
, ds
, root
, PR_FALSE
, relativePath
);
1657 rv
= rdfs
->GetResource(NS_LITERAL_CSTRING("urn:mozilla:stylesheets"),
1658 getter_AddRefs(root
));
1659 if (NS_SUCCEEDED(rv
))
1660 ProcessOverlays(fd
, ds
, root
, NS_LITERAL_CSTRING("style"));
1663 rv
= rdfs
->GetResource(NS_LITERAL_CSTRING("urn:mozilla:locale:root"),
1664 getter_AddRefs(root
));
1665 if (NS_SUCCEEDED(rv
))
1666 ProcessProvider(fd
, rdfs
, ds
, root
, PR_TRUE
, relativePath
);
1668 rv
= rdfs
->GetResource(NS_LITERAL_CSTRING("urn:mozilla:overlays"),
1669 getter_AddRefs(root
));
1670 if (NS_SUCCEEDED(rv
))
1671 ProcessOverlays(fd
, ds
, root
, NS_LITERAL_CSTRING("overlay"));
1673 /* content packages are easier, but different */
1675 rv
= rdfs
->GetResource(NS_LITERAL_CSTRING("urn:mozilla:package:root"),
1676 getter_AddRefs(root
));
1678 nsCOMPtr
<nsISimpleEnumerator
> packages
;
1679 if (NS_SUCCEEDED(rv
))
1680 rv
= GetContainerEnumerator(ds
, root
, getter_AddRefs(packages
));
1682 if (NS_SUCCEEDED(rv
)) {
1684 nsCOMPtr
<nsISupports
> next
;
1685 nsCOMPtr
<nsIRDFResource
> package
;
1687 while (NS_SUCCEEDED(packages
->HasMoreElements(&more
)) && more
) {
1688 packages
->GetNext(getter_AddRefs(next
));
1690 package
= do_QueryInterface(next
);
1692 NS_WARNING("Arc from urn:mozilla:package:root points to non-resource node.");
1697 FollowLiteral(ds
, package
, namearc
, name
);
1701 nsCAutoString isPlatform
;
1702 FollowLiteral(ds
, package
, platformarc
, isPlatform
);
1703 name
.Insert(NS_LITERAL_CSTRING("content\t"), 0);
1705 name
.Append(relativePath
);
1706 if (!isPlatform
.IsEmpty())
1707 name
.AppendLiteral("\tplatform");
1709 name
.AppendLiteral(NS_LINEBREAK
);
1710 PR_Write(fd
, name
.get(), name
.Length());
1721 GetResourceName(nsIRDFResource
* res
, nsACString
& result
)
1723 // we need to get the provider name. Instead of doing something sane,
1724 // we munge the resource URI, looking from the right for colons.
1726 nsCAutoString providerURI
;
1727 res
->GetValueUTF8(providerURI
);
1729 PRInt32 found
= providerURI
.RFindChar(':');
1730 if (found
== kNotFound
) {
1735 result
.Assign(Substring(providerURI
, found
+ 1));
1740 nsChromeRegistry::ProcessProvider(PRFileDesc
*fd
, nsIRDFService
* aRDFs
,
1741 nsIRDFDataSource
* aDS
, nsIRDFResource
* aRoot
,
1742 PRBool aIsLocale
, const nsACString
& aBaseURL
)
1744 NS_NAMED_LITERAL_CSTRING(kSlash
, "/");
1745 NS_NAMED_LITERAL_CSTRING(kTab
, "\t");
1749 nsCOMPtr
<nsIRDFResource
> packagesarc
;
1750 aRDFs
->GetResource(NS_LITERAL_CSTRING(kURICHROME_packages
),
1751 getter_AddRefs(packagesarc
));
1752 if (!packagesarc
) return;
1754 nsCOMPtr
<nsISimpleEnumerator
> providers
;
1755 rv
= GetContainerEnumerator(aDS
, aRoot
, getter_AddRefs(providers
));
1756 if (NS_FAILED(rv
)) {
1760 nsCOMPtr
<nsISupports
> next
;
1763 while (NS_SUCCEEDED(providers
->HasMoreElements(&more
)) && more
) {
1764 providers
->GetNext(getter_AddRefs(next
));
1765 NS_ASSERTION(next
, "GetNext failed after HasMoreElements succeeded.");
1767 nsCOMPtr
<nsIRDFResource
> provider (do_QueryInterface(next
));
1769 NS_WARNING("Provider isn't a nsIRDFResource.");
1773 nsCAutoString providerName
;
1774 GetResourceName(provider
, providerName
);
1775 if (providerName
.IsEmpty()) {
1776 NS_WARNING("Couldn't calculate resource name.");
1780 nsCOMPtr
<nsIRDFResource
> packages
;
1781 FollowResource(aDS
, provider
, packagesarc
, getter_AddRefs(packages
));
1783 NS_WARNING("No chrome:packages arc found!");
1788 nsCOMPtr
<nsISimpleEnumerator
> packageList
;
1789 rv
= GetContainerEnumerator(aDS
, packages
, getter_AddRefs(packageList
), &count
);
1790 if (NS_FAILED(rv
)) {
1791 NS_WARNING("chrome:packages was not a sequence.");
1795 nsCOMPtr
<nsISupports
> nextPackage
;
1797 PRBool morePackages
;
1798 while (NS_SUCCEEDED(packageList
->HasMoreElements(&morePackages
)) &&
1800 packageList
->GetNext(getter_AddRefs(nextPackage
));
1802 nsCOMPtr
<nsIRDFResource
> packageRes (do_QueryInterface(nextPackage
));
1804 NS_WARNING("chrome:packages Seq points to a non-resource!");
1808 nsCAutoString packageName
;
1809 GetResourceName(packageRes
, packageName
);
1810 if (packageName
.IsEmpty()) {
1811 NS_WARNING("couldn't extract a package name.");
1818 line
.AppendLiteral("locale\t");
1820 line
.AppendLiteral("skin\t");
1822 line
+= packageName
+ kTab
+ providerName
+ kTab
+ aBaseURL
;
1824 line
+= packageName
+ kSlash
;
1826 line
.AppendLiteral(NS_LINEBREAK
);
1827 PR_Write(fd
, line
.get(), line
.Length());
1833 GetLiteralText(nsIRDFLiteral
* lit
, nsACString
& result
)
1835 const PRUnichar
* value
;
1836 lit
->GetValueConst(&value
);
1837 CopyUTF16toUTF8(value
, result
);
1841 nsChromeRegistry::ProcessOverlays(PRFileDesc
*fd
, nsIRDFDataSource
* aDS
,
1842 nsIRDFResource
* aRoot
,
1843 const nsCSubstring
& aType
)
1845 NS_NAMED_LITERAL_CSTRING(kTab
, "\t");
1846 NS_NAMED_LITERAL_CSTRING(kLinebreak
, NS_LINEBREAK
);
1850 nsCOMPtr
<nsISimpleEnumerator
> overlaids
;
1851 rv
= GetContainerEnumerator(aDS
, aRoot
, getter_AddRefs(overlaids
));
1852 if (NS_FAILED(rv
)) {
1856 nsCOMPtr
<nsISupports
> next
;
1858 while (NS_SUCCEEDED(overlaids
->HasMoreElements(&more
)) && more
) {
1859 overlaids
->GetNext(getter_AddRefs(next
));
1860 NS_ASSERTION(next
, "GetNext failed after HasMoreElements succeeded.");
1862 nsCOMPtr
<nsIRDFResource
> overlaid (do_QueryInterface(next
));
1864 NS_WARNING("Overlay arc is not a nsIRDFResource.");
1868 nsCAutoString overlaidName
;
1869 overlaid
->GetValueUTF8(overlaidName
);
1871 nsCOMPtr
<nsISimpleEnumerator
> overlays
;
1872 rv
= GetContainerEnumerator(aDS
, overlaid
, getter_AddRefs(overlays
));
1876 while (NS_SUCCEEDED(overlays
->HasMoreElements(&more
)) && more
) {
1877 overlays
->GetNext(getter_AddRefs(next
));
1878 NS_ASSERTION(next
, "GetNext failed after HasMoreElements succeeded.");
1880 nsCOMPtr
<nsIRDFLiteral
> overlay (do_QueryInterface(next
));
1882 NS_WARNING("Overlay was not an RDF literal.");
1886 nsCAutoString overlayName
;
1887 GetLiteralText(overlay
, overlayName
);
1889 overlayName
.Insert(aType
+ kTab
+ overlaidName
+ kTab
, 0);
1890 overlayName
.Append(kLinebreak
);
1891 PR_Write(fd
, overlayName
.get(), overlayName
.Length());
1899 nsChromeRegistry::ProcessContentsManifest(nsIURI
* aOldManifest
, nsIURI
* aFile
,
1900 nsIURI
* aBaseURI
, PRBool aAppend
,
1903 return NS_ERROR_NOT_IMPLEMENTED
;
1909 nsChromeRegistry::ProcessManifest(nsILocalFile
* aManifest
, PRBool aSkinOnly
)
1914 rv
= aManifest
->OpenNSPRFileDesc(PR_RDONLY
, 0, &fd
);
1915 NS_ENSURE_SUCCESS(rv
, rv
);
1920 size
= PR_Available(fd
);
1922 rv
= NS_ERROR_UNEXPECTED
;
1926 buf
= (char *) malloc(size
+ 1);
1928 rv
= NS_ERROR_OUT_OF_MEMORY
;
1932 n
= PR_Read(fd
, buf
, size
);
1935 rv
= ProcessManifestBuffer(buf
, size
, aManifest
, aSkinOnly
);
1944 static const char kWhitespace
[] = "\t ";
1945 static const char kNewlines
[] = "\r\n";
1948 * Check for a modifier flag of the following forms:
1949 * "flag" (same as "true")
1951 * "flag="no|false|0"
1952 * @param aFlag The flag to compare.
1953 * @param aData The tokenized data to check; this is lowercased
1954 * before being passed in.
1955 * @param aResult If the flag is found, the value is assigned here.
1956 * @return Whether the flag was handled.
1959 CheckFlag(const nsSubstring
& aFlag
, const nsSubstring
& aData
, PRBool
& aResult
)
1961 if (!StringBeginsWith(aData
, aFlag
))
1964 if (aFlag
.Length() == aData
.Length()) {
1965 // the data is simply "flag", which is the same as "flag=yes"
1970 if (aData
.CharAt(aFlag
.Length()) != '=') {
1971 // the data is "flag2=", which is not anything we care about
1975 if (aData
.Length() == aFlag
.Length() + 1) {
1980 switch (aData
.CharAt(aFlag
.Length() + 1)) {
2004 * Check for a modifier flag of the following form:
2007 * @param aFlag The flag to compare.
2008 * @param aData The tokenized data to check; this is lowercased
2009 * before being passed in.
2010 * @param aValue The value that is expected.
2011 * @param aResult If this is "ok" when passed in, this is left alone.
2012 * Otherwise if the flag is found it is set to eBad or eOK.
2013 * @return Whether the flag was handled.
2016 CheckStringFlag(const nsSubstring
& aFlag
, const nsSubstring
& aData
,
2017 const nsSubstring
& aValue
, TriState
& aResult
)
2019 if (aData
.Length() < aFlag
.Length() + 1)
2022 if (!StringBeginsWith(aData
, aFlag
))
2025 PRBool comparison
= PR_TRUE
;
2026 if (aData
[aFlag
.Length()] != '=') {
2027 if (aData
[aFlag
.Length()] == '!' &&
2028 aData
.Length() >= aFlag
.Length() + 2 &&
2029 aData
[aFlag
.Length() + 1] == '=')
2030 comparison
= PR_FALSE
;
2035 if (aResult
!= eOK
) {
2036 nsDependentSubstring testdata
= Substring(aData
, aFlag
.Length() + (comparison
? 1 : 2));
2037 if (testdata
.Equals(aValue
))
2038 aResult
= comparison
? eOK
: eBad
;
2040 aResult
= comparison
? eBad
: eOK
;
2047 * Check for a modifier flag of the following form:
2053 * @param aFlag The flag to compare.
2054 * @param aData The tokenized data to check; this is lowercased
2055 * before being passed in.
2056 * @param aValue The value that is expected. If this is empty then no
2057 * comparison will match.
2058 * @param aChecker the version checker to use. If null, aResult will always
2060 * @param aResult If this is eOK when passed in, this is left alone.
2061 * Otherwise if the flag is found it is set to eBad or eOK.
2062 * @return Whether the flag was handled.
2065 #define COMPARE_EQ 1 << 0
2066 #define COMPARE_LT 1 << 1
2067 #define COMPARE_GT 1 << 2
2070 CheckVersionFlag(const nsSubstring
& aFlag
, const nsSubstring
& aData
,
2071 const nsSubstring
& aValue
, nsIVersionComparator
* aChecker
,
2074 if (aData
.Length() < aFlag
.Length() + 2)
2077 if (!StringBeginsWith(aData
, aFlag
))
2080 if (aValue
.Length() == 0) {
2086 PRUint32 comparison
;
2087 nsAutoString testdata
;
2089 switch (aData
[aFlag
.Length()]) {
2091 comparison
= COMPARE_EQ
;
2092 testdata
= Substring(aData
, aFlag
.Length() + 1);
2096 if (aData
[aFlag
.Length() + 1] == '=') {
2097 comparison
= COMPARE_EQ
| COMPARE_LT
;
2098 testdata
= Substring(aData
, aFlag
.Length() + 2);
2101 comparison
= COMPARE_LT
;
2102 testdata
= Substring(aData
, aFlag
.Length() + 1);
2107 if (aData
[aFlag
.Length() + 1] == '=') {
2108 comparison
= COMPARE_EQ
| COMPARE_GT
;
2109 testdata
= Substring(aData
, aFlag
.Length() + 2);
2112 comparison
= COMPARE_GT
;
2113 testdata
= Substring(aData
, aFlag
.Length() + 1);
2121 if (testdata
.Length() == 0)
2124 if (aResult
!= eOK
) {
2130 nsresult rv
= aChecker
->Compare(NS_ConvertUTF16toUTF8(aValue
),
2131 NS_ConvertUTF16toUTF8(testdata
), &c
);
2132 if (NS_FAILED(rv
)) {
2136 if ((c
== 0 && comparison
& COMPARE_EQ
) ||
2137 (c
< 0 && comparison
& COMPARE_LT
) ||
2138 (c
> 0 && comparison
& COMPARE_GT
))
2150 EnsureLowerCase(char *aBuf
)
2152 for (; *aBuf
; ++aBuf
) {
2154 if (ch
>= 'A' && ch
<= 'Z')
2155 *aBuf
= ch
+ 'a' - 'A';
2160 nsChromeRegistry::ProcessManifestBuffer(char *buf
, PRInt32 length
,
2161 nsILocalFile
* aManifest
,
2166 NS_NAMED_LITERAL_STRING(kPlatform
, "platform");
2167 NS_NAMED_LITERAL_STRING(kXPCNativeWrappers
, "xpcnativewrappers");
2168 NS_NAMED_LITERAL_STRING(kContentAccessible
, "contentaccessible");
2169 NS_NAMED_LITERAL_STRING(kApplication
, "application");
2170 NS_NAMED_LITERAL_STRING(kAppVersion
, "appversion");
2171 NS_NAMED_LITERAL_STRING(kOs
, "os");
2172 NS_NAMED_LITERAL_STRING(kOsVersion
, "osversion");
2174 nsCOMPtr
<nsIIOService
> io (do_GetIOService());
2175 if (!io
) return NS_ERROR_FAILURE
;
2177 nsCOMPtr
<nsIProtocolHandler
> ph
;
2178 rv
= io
->GetProtocolHandler("resource", getter_AddRefs(ph
));
2179 NS_ENSURE_SUCCESS(rv
, rv
);
2181 nsCOMPtr
<nsIResProtocolHandler
> rph (do_QueryInterface(ph
));
2182 if (!rph
) return NS_ERROR_FAILURE
;
2184 nsCOMPtr
<nsIURI
> manifestURI
;
2185 rv
= io
->NewFileURI(aManifest
, getter_AddRefs(manifestURI
));
2186 NS_ENSURE_SUCCESS(rv
, rv
);
2188 nsCOMPtr
<nsIXPConnect
> xpc (do_GetService("@mozilla.org/js/xpc/XPConnect;1"));
2189 nsCOMPtr
<nsIVersionComparator
> vc (do_GetService("@mozilla.org/xpcom/version-comparator;1"));
2192 nsAutoString appVersion
;
2193 nsAutoString osTarget
;
2194 nsCOMPtr
<nsIXULAppInfo
> xapp (do_GetService(XULAPPINFO_SERVICE_CONTRACTID
));
2197 rv
= xapp
->GetID(s
);
2198 if (NS_SUCCEEDED(rv
))
2199 CopyUTF8toUTF16(s
, appID
);
2201 rv
= xapp
->GetVersion(s
);
2202 if (NS_SUCCEEDED(rv
))
2203 CopyUTF8toUTF16(s
, appVersion
);
2205 nsCOMPtr
<nsIXULRuntime
> xruntime (do_QueryInterface(xapp
));
2207 rv
= xruntime
->GetOS(s
);
2208 if (NS_SUCCEEDED(rv
)) {
2209 CopyUTF8toUTF16(s
, osTarget
);
2210 ToLowerCase(osTarget
);
2215 nsAutoString osVersion
;
2217 OSVERSIONINFO info
= { sizeof(OSVERSIONINFO
) };
2218 if (GetVersionEx(&info
)) {
2219 nsTextFormatter::ssprintf(osVersion
, NS_LITERAL_STRING("%ld.%ld").get(),
2220 info
.dwMajorVersion
,
2221 info
.dwMinorVersion
);
2223 #elif defined(XP_MACOSX)
2224 long majorVersion
, minorVersion
;
2225 if ((Gestalt(gestaltSystemVersionMajor
, &majorVersion
) == noErr
) &&
2226 (Gestalt(gestaltSystemVersionMinor
, &minorVersion
) == noErr
)) {
2227 nsTextFormatter::ssprintf(osVersion
, NS_LITERAL_STRING("%ld.%ld").get(),
2231 #elif defined(MOZ_WIDGET_GTK2)
2232 nsTextFormatter::ssprintf(osVersion
, NS_LITERAL_STRING("%ld.%ld").get(),
2238 char *newline
= buf
;
2241 // outer loop tokenizes by newline
2242 while (nsnull
!= (token
= nsCRT::strtok(newline
, kNewlines
, &newline
))) {
2245 if (*token
== '#') // ignore lines that begin with # as comments
2248 char *whitespace
= token
;
2249 token
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2250 if (!token
) continue;
2252 if (!strcmp(token
, "content")) {
2254 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2255 "Warning: Ignoring content registration in skin-only manifest.");
2258 char *package
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2259 char *uri
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2260 if (!package
|| !uri
) {
2261 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2262 "Warning: Malformed content registration.");
2266 EnsureLowerCase(package
);
2268 // NOTE: We check for platform and xpcnativewrappers modifiers on
2269 // content packages, but they are *applied* to content|skin|locale.
2271 PRBool platform
= PR_FALSE
;
2272 PRBool xpcNativeWrappers
= PR_TRUE
;
2273 PRBool contentAccessible
= PR_FALSE
;
2274 TriState stAppVersion
= eUnspecified
;
2275 TriState stApp
= eUnspecified
;
2276 TriState stOsVersion
= eUnspecified
;
2277 TriState stOs
= eUnspecified
;
2279 PRBool badFlag
= PR_FALSE
;
2281 while (nsnull
!= (token
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
)) &&
2283 NS_ConvertASCIItoUTF16
wtoken(token
);
2284 ToLowerCase(wtoken
);
2286 if (CheckFlag(kPlatform
, wtoken
, platform
) ||
2287 CheckFlag(kXPCNativeWrappers
, wtoken
, xpcNativeWrappers
) ||
2288 CheckFlag(kContentAccessible
, wtoken
, contentAccessible
) ||
2289 CheckStringFlag(kApplication
, wtoken
, appID
, stApp
) ||
2290 CheckStringFlag(kOs
, wtoken
, osTarget
, stOs
) ||
2291 CheckVersionFlag(kOsVersion
, wtoken
, osVersion
, vc
, stOsVersion
) ||
2292 CheckVersionFlag(kAppVersion
, wtoken
, appVersion
, vc
, stAppVersion
))
2295 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2296 "Warning: Unrecognized chrome registration modifier '%s'.",
2301 if (badFlag
|| stApp
== eBad
|| stAppVersion
== eBad
||
2302 stOs
== eBad
|| stOsVersion
== eBad
)
2305 nsCOMPtr
<nsIURI
> resolved
;
2306 rv
= io
->NewURI(nsDependentCString(uri
), nsnull
, manifestURI
,
2307 getter_AddRefs(resolved
));
2311 PackageEntry
* entry
=
2312 static_cast<PackageEntry
*>(PL_DHashTableOperate(&mPackagesHash
,
2313 & (const nsACString
&) nsDependentCString(package
),
2316 return NS_ERROR_OUT_OF_MEMORY
;
2318 entry
->baseURI
= resolved
;
2321 entry
->flags
|= PackageEntry::PLATFORM_PACKAGE
;
2322 if (xpcNativeWrappers
)
2323 entry
->flags
|= PackageEntry::XPCNATIVEWRAPPERS
;
2324 if (contentAccessible
)
2325 entry
->flags
|= PackageEntry::CONTENT_ACCESSIBLE
;
2327 nsCAutoString
urlp("chrome://");
2328 urlp
.Append(package
);
2331 rv
= xpc
->FlagSystemFilenamePrefix(urlp
.get(), xpcNativeWrappers
);
2332 NS_ENSURE_SUCCESS(rv
, rv
);
2335 else if (!strcmp(token
, "locale")) {
2337 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2338 "Warning: Ignoring locale registration in skin-only manifest.");
2341 char *package
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2342 char *provider
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2343 char *uri
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2344 if (!package
|| !provider
|| !uri
) {
2345 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2346 "Warning: Malformed locale registration.");
2350 EnsureLowerCase(package
);
2352 TriState stAppVersion
= eUnspecified
;
2353 TriState stApp
= eUnspecified
;
2354 TriState stOs
= eUnspecified
;
2355 TriState stOsVersion
= eUnspecified
;
2357 PRBool badFlag
= PR_FALSE
;
2359 while (nsnull
!= (token
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
)) &&
2361 NS_ConvertASCIItoUTF16
wtoken(token
);
2362 ToLowerCase(wtoken
);
2364 if (CheckStringFlag(kApplication
, wtoken
, appID
, stApp
) ||
2365 CheckStringFlag(kOs
, wtoken
, osTarget
, stOs
) ||
2366 CheckVersionFlag(kOsVersion
, wtoken
, osVersion
, vc
, stOsVersion
) ||
2367 CheckVersionFlag(kAppVersion
, wtoken
, appVersion
, vc
, stAppVersion
))
2370 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2371 "Warning: Unrecognized chrome registration modifier '%s'.",
2376 if (badFlag
|| stApp
== eBad
|| stAppVersion
== eBad
||
2377 stOs
== eBad
|| stOsVersion
== eBad
)
2380 nsCOMPtr
<nsIURI
> resolved
;
2381 rv
= io
->NewURI(nsDependentCString(uri
), nsnull
, manifestURI
,
2382 getter_AddRefs(resolved
));
2386 PackageEntry
* entry
=
2387 static_cast<PackageEntry
*>(PL_DHashTableOperate(&mPackagesHash
,
2388 & (const nsACString
&) nsDependentCString(package
),
2391 return NS_ERROR_OUT_OF_MEMORY
;
2393 entry
->locales
.SetBase(nsDependentCString(provider
), resolved
);
2395 else if (!strcmp(token
, "skin")) {
2396 char *package
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2397 char *provider
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2398 char *uri
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2399 if (!package
|| !provider
|| !uri
) {
2400 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2401 "Warning: Malformed skin registration.");
2405 EnsureLowerCase(package
);
2407 TriState stAppVersion
= eUnspecified
;
2408 TriState stApp
= eUnspecified
;
2409 TriState stOs
= eUnspecified
;
2410 TriState stOsVersion
= eUnspecified
;
2412 PRBool badFlag
= PR_FALSE
;
2414 while (nsnull
!= (token
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
)) &&
2416 NS_ConvertASCIItoUTF16
wtoken(token
);
2417 ToLowerCase(wtoken
);
2419 if (CheckStringFlag(kApplication
, wtoken
, appID
, stApp
) ||
2420 CheckStringFlag(kOs
, wtoken
, osTarget
, stOs
) ||
2421 CheckVersionFlag(kOsVersion
, wtoken
, osVersion
, vc
, stOsVersion
) ||
2422 CheckVersionFlag(kAppVersion
, wtoken
, appVersion
, vc
, stAppVersion
))
2425 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2426 "Warning: Unrecognized chrome registration modifier '%s'.",
2431 if (badFlag
|| stApp
== eBad
|| stAppVersion
== eBad
||
2432 stOs
== eBad
|| stOsVersion
== eBad
)
2435 nsCOMPtr
<nsIURI
> resolved
;
2436 rv
= io
->NewURI(nsDependentCString(uri
), nsnull
, manifestURI
,
2437 getter_AddRefs(resolved
));
2441 PackageEntry
* entry
=
2442 static_cast<PackageEntry
*>(PL_DHashTableOperate(&mPackagesHash
,
2443 & (const nsACString
&) nsDependentCString(package
),
2446 return NS_ERROR_OUT_OF_MEMORY
;
2448 entry
->skins
.SetBase(nsDependentCString(provider
), resolved
);
2450 else if (!strcmp(token
, "overlay")) {
2452 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2453 "Warning: Ignoring overlay registration in skin-only manifest.");
2456 char *base
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2457 char *overlay
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2458 if (!base
|| !overlay
) {
2459 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2460 "Warning: malformed chrome overlay instruction.");
2464 TriState stAppVersion
= eUnspecified
;
2465 TriState stApp
= eUnspecified
;
2466 TriState stOs
= eUnspecified
;
2467 TriState stOsVersion
= eUnspecified
;
2469 PRBool badFlag
= PR_FALSE
;
2471 while (nsnull
!= (token
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
)) &&
2473 NS_ConvertASCIItoUTF16
wtoken(token
);
2474 ToLowerCase(wtoken
);
2476 if (CheckStringFlag(kApplication
, wtoken
, appID
, stApp
) ||
2477 CheckStringFlag(kOs
, wtoken
, osTarget
, stOs
) ||
2478 CheckVersionFlag(kOsVersion
, wtoken
, osVersion
, vc
, stOsVersion
) ||
2479 CheckVersionFlag(kAppVersion
, wtoken
, appVersion
, vc
, stAppVersion
))
2482 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2483 "Warning: Unrecognized chrome registration modifier '%s'.",
2488 if (badFlag
|| stApp
== eBad
|| stAppVersion
== eBad
||
2489 stOs
== eBad
|| stOsVersion
== eBad
)
2492 nsCOMPtr
<nsIURI
> baseuri
, overlayuri
;
2493 rv
= io
->NewURI(nsDependentCString(base
), nsnull
, nsnull
,
2494 getter_AddRefs(baseuri
));
2495 rv
|= io
->NewURI(nsDependentCString(overlay
), nsnull
, nsnull
,
2496 getter_AddRefs(overlayuri
));
2497 if (NS_FAILED(rv
)) {
2498 NS_WARNING("Could not make URIs for overlay directive. Ignoring.");
2502 mOverlayHash
.Add(baseuri
, overlayuri
);
2504 else if (!strcmp(token
, "style")) {
2505 char *base
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2506 char *overlay
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2507 if (!base
|| !overlay
) {
2508 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2509 "Warning: malformed chrome style instruction.");
2513 TriState stAppVersion
= eUnspecified
;
2514 TriState stApp
= eUnspecified
;
2515 TriState stOs
= eUnspecified
;
2516 TriState stOsVersion
= eUnspecified
;
2518 PRBool badFlag
= PR_FALSE
;
2520 while (nsnull
!= (token
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
)) &&
2522 NS_ConvertASCIItoUTF16
wtoken(token
);
2523 ToLowerCase(wtoken
);
2525 if (CheckStringFlag(kApplication
, wtoken
, appID
, stApp
) ||
2526 CheckStringFlag(kOs
, wtoken
, osTarget
, stOs
) ||
2527 CheckVersionFlag(kOsVersion
, wtoken
, osVersion
, vc
, stOsVersion
) ||
2528 CheckVersionFlag(kAppVersion
, wtoken
, appVersion
, vc
, stAppVersion
))
2531 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2532 "Warning: Unrecognized chrome registration modifier '%s'.",
2537 if (badFlag
|| stApp
== eBad
|| stAppVersion
== eBad
||
2538 stOs
== eBad
|| stOsVersion
== eBad
)
2541 nsCOMPtr
<nsIURI
> baseuri
, overlayuri
;
2542 rv
= io
->NewURI(nsDependentCString(base
), nsnull
, nsnull
,
2543 getter_AddRefs(baseuri
));
2544 rv
|= io
->NewURI(nsDependentCString(overlay
), nsnull
, nsnull
,
2545 getter_AddRefs(overlayuri
));
2549 mStyleHash
.Add(baseuri
, overlayuri
);
2551 else if (!strcmp(token
, "override")) {
2553 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2554 "Warning: Ignoring override registration in skin-only manifest.");
2558 char *chrome
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2559 char *resolved
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2560 if (!chrome
|| !resolved
) {
2561 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2562 "Warning: malformed chrome override instruction.");
2566 TriState stAppVersion
= eUnspecified
;
2567 TriState stApp
= eUnspecified
;
2568 TriState stOs
= eUnspecified
;
2569 TriState stOsVersion
= eUnspecified
;
2571 PRBool badFlag
= PR_FALSE
;
2573 while (nsnull
!= (token
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
)) &&
2575 NS_ConvertASCIItoUTF16
wtoken(token
);
2576 ToLowerCase(wtoken
);
2578 if (CheckStringFlag(kApplication
, wtoken
, appID
, stApp
) ||
2579 CheckStringFlag(kOs
, wtoken
, osTarget
, stOs
) ||
2580 CheckVersionFlag(kOsVersion
, wtoken
, osVersion
, vc
, stOsVersion
) ||
2581 CheckVersionFlag(kAppVersion
, wtoken
, appVersion
, vc
, stAppVersion
))
2584 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2585 "Warning: Unrecognized chrome registration modifier '%s'.",
2590 if (badFlag
|| stApp
== eBad
|| stAppVersion
== eBad
||
2591 stOs
== eBad
|| stOsVersion
== eBad
)
2594 nsCOMPtr
<nsIURI
> chromeuri
, resolveduri
;
2595 rv
= io
->NewURI(nsDependentCString(chrome
), nsnull
, nsnull
,
2596 getter_AddRefs(chromeuri
));
2597 rv
|= io
->NewURI(nsDependentCString(resolved
), nsnull
, manifestURI
,
2598 getter_AddRefs(resolveduri
));
2602 mOverrideTable
.Put(chromeuri
, resolveduri
);
2604 else if (!strcmp(token
, "resource")) {
2606 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2607 "Warning: Ignoring resource registration in skin-only manifest.");
2611 char *package
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2612 char *uri
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
);
2613 if (!package
|| !uri
) {
2614 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2615 "Warning: Malformed resource registration.");
2619 EnsureLowerCase(package
);
2621 TriState stAppVersion
= eUnspecified
;
2622 TriState stApp
= eUnspecified
;
2623 TriState stOsVersion
= eUnspecified
;
2624 TriState stOs
= eUnspecified
;
2626 PRBool badFlag
= PR_FALSE
;
2628 while (nsnull
!= (token
= nsCRT::strtok(whitespace
, kWhitespace
, &whitespace
)) &&
2630 NS_ConvertASCIItoUTF16
wtoken(token
);
2631 ToLowerCase(wtoken
);
2633 if (CheckStringFlag(kApplication
, wtoken
, appID
, stApp
) ||
2634 CheckStringFlag(kOs
, wtoken
, osTarget
, stOs
) ||
2635 CheckVersionFlag(kOsVersion
, wtoken
, osVersion
, vc
, stOsVersion
) ||
2636 CheckVersionFlag(kAppVersion
, wtoken
, appVersion
, vc
, stAppVersion
))
2639 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2640 "Warning: Unrecognized chrome registration modifier '%s'.",
2645 if (badFlag
|| stApp
== eBad
|| stAppVersion
== eBad
||
2646 stOs
== eBad
|| stOsVersion
== eBad
)
2649 nsDependentCString
host(package
);
2652 rv
= rph
->HasSubstitution(host
, &exists
);
2653 NS_ENSURE_SUCCESS(rv
, rv
);
2655 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2656 "Warning: Duplicate resource declaration for '%s' ignored.",
2661 nsCOMPtr
<nsIURI
> resolved
;
2662 rv
= io
->NewURI(nsDependentCString(uri
), nsnull
, manifestURI
,
2663 getter_AddRefs(resolved
));
2667 rv
= rph
->SetSubstitution(host
, resolved
);
2668 NS_ENSURE_SUCCESS(rv
, rv
);
2671 LogMessageWithContext(manifestURI
, line
, nsIScriptError::warningFlag
,
2672 "Warning: Ignoring unrecognized chrome manifest instruction.");