mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 568691 part C - Register all components based on reading .manifest files from the components directories. Binary components auto-register using "binary-component name.dll". JS components register using "component CID file.js" "contract @mozilla.org/contract;1 CID" and "category categoryname keyname value".
This patch has some bugs, specifically we stop looking for .manifest files in chrome/. I will fix that in a followup. It also probably breaks non-libxul builds because of ordering issues. Another followup will actually fix our in-tree JS components and add build machinery for creating a proper components.manifest file.
This commit is contained in:
parent
78481b5e53
commit
492155b10e
@ -43,16 +43,12 @@ VPATH = @srcdir@
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = chrome
|
||||
LIBRARY_NAME = chrome
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = nsChromeModule
|
||||
GRE_MODULE = 1
|
||||
LIBRARY_NAME = chrome_s
|
||||
LIBXUL_LIBRARY = 1
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
|
||||
CPPSRCS = \
|
||||
nsChromeFactory.cpp \
|
||||
nsChromeRegistry.cpp \
|
||||
nsChromeProtocolHandler.cpp \
|
||||
$(NULL)
|
||||
@ -76,3 +72,7 @@ ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
|
||||
CXXFLAGS += $(MOZ_GTK2_CFLAGS)
|
||||
endif
|
||||
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(topsrcdir)/xpcom/components \
|
||||
-I$(DEPTH)/xpcom \
|
||||
$(NULL)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -55,6 +55,9 @@
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsIResProtocolHandler.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
||||
struct PRFileDesc;
|
||||
class nsIAtom;
|
||||
@ -121,19 +124,41 @@ private:
|
||||
static nsresult GetProviderAndPath(nsIURL* aChromeURL,
|
||||
nsACString& aProvider, nsACString& aPath);
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
NS_HIDDEN_(void) ProcessProvider(PRFileDesc *fd, nsIRDFService* aRDFs,
|
||||
nsIRDFDataSource* ds, nsIRDFResource* aRoot,
|
||||
PRBool aIsLocale, const nsACString& aBaseURL);
|
||||
NS_HIDDEN_(void) ProcessOverlays(PRFileDesc *fd, nsIRDFDataSource* ds,
|
||||
nsIRDFResource* aRoot,
|
||||
const nsCSubstring& aType);
|
||||
#endif
|
||||
public:
|
||||
struct ManifestProcessingContext
|
||||
{
|
||||
ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile)
|
||||
: mType(aType)
|
||||
, mFile(aFile)
|
||||
{ }
|
||||
~ManifestProcessingContext()
|
||||
{ }
|
||||
|
||||
NS_HIDDEN_(nsresult) ProcessManifest(nsILocalFile* aManifest, PRBool aSkinOnly);
|
||||
NS_HIDDEN_(nsresult) ProcessManifestBuffer(char *aBuffer, PRInt32 aLength, nsILocalFile* aManifest, PRBool aSkinOnly);
|
||||
NS_HIDDEN_(nsresult) ProcessNewChromeFile(nsILocalFile *aListFile, nsIURI* aManifest);
|
||||
NS_HIDDEN_(nsresult) ProcessNewChromeBuffer(char *aBuffer, PRInt32 aLength, nsIURI* aManifest);
|
||||
nsIURI* GetManifestURI();
|
||||
nsIXPConnect* GetXPConnect();
|
||||
|
||||
already_AddRefed<nsIURI> ResolveURI(const char* uri);
|
||||
|
||||
NSLocationType mType;
|
||||
nsCOMPtr<nsILocalFile> mFile;
|
||||
nsCOMPtr<nsIURI> mManifestURI;
|
||||
nsCOMPtr<nsIXPConnect> mXPConnect;
|
||||
};
|
||||
|
||||
void ManifestContent(ManifestProcessingContext& cx, int lineno,
|
||||
char *const * argv, bool platform, bool contentaccessible);
|
||||
void ManifestLocale(ManifestProcessingContext& cx, int lineno,
|
||||
char *const * argv, bool platform, bool contentaccessible);
|
||||
void ManifestSkin(ManifestProcessingContext& cx, int lineno,
|
||||
char *const * argv, bool platform, bool contentaccessible);
|
||||
void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
|
||||
char *const * argv, bool platform, bool contentaccessible);
|
||||
void ManifestStyle(ManifestProcessingContext& cx, int lineno,
|
||||
char *const * argv, bool platform, bool contentaccessible);
|
||||
void ManifestOverride(ManifestProcessingContext& cx, int lineno,
|
||||
char *const * argv, bool platform, bool contentaccessible);
|
||||
void ManifestResource(ManifestProcessingContext& cx, int lineno,
|
||||
char *const * argv, bool platform, bool contentaccessible);
|
||||
|
||||
public:
|
||||
struct ProviderEntry
|
||||
|
@ -755,7 +755,7 @@ mozJSComponentLoader::LoadModule(nsILocalFile* aComponentFile)
|
||||
|
||||
JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter);
|
||||
|
||||
jsval argv[2], retval, NSGetFactory_val;
|
||||
jsval NSGetFactory_val;
|
||||
|
||||
if (!JS_GetProperty(cx, entry->global, "NSGetFactory", &NSGetFactory_val) ||
|
||||
JSVAL_IS_VOID(NSGetFactory_val)) {
|
||||
@ -772,14 +772,14 @@ mozJSComponentLoader::LoadModule(nsILocalFile* aComponentFile)
|
||||
}
|
||||
|
||||
JSObject *jsGetFactoryObj;
|
||||
if (!JS_ValueToObject(cx, retval, &jsGetFactoryObj) ||
|
||||
if (!JS_ValueToObject(cx, NSGetFactory_val, &jsGetFactoryObj) ||
|
||||
!jsGetFactoryObj) {
|
||||
/* XXX report error properly */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rv = xpc->WrapJS(cx, jsGetFactoryObj,
|
||||
NS_GET_IID(xpcIJSGetFactory), getter_AddRefs(entry->getfactory));
|
||||
NS_GET_IID(xpcIJSGetFactory), getter_AddRefs(entry->getfactoryobj));
|
||||
if (NS_FAILED(rv)) {
|
||||
/* XXX report error properly */
|
||||
#ifdef DEBUG
|
||||
@ -793,9 +793,7 @@ mozJSComponentLoader::LoadModule(nsILocalFile* aComponentFile)
|
||||
return NULL;
|
||||
|
||||
// The hash owns the ModuleEntry now, forget about it
|
||||
entry.forget();
|
||||
|
||||
return entry;
|
||||
return entry.forget();
|
||||
}
|
||||
|
||||
// Some stack based classes for cleaning up on early return
|
||||
@ -1377,6 +1375,13 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponent,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ PLDHashOperator
|
||||
mozJSComponentLoader::ClearModules(nsIHashable* key, ModuleEntry*& entry, void* cx)
|
||||
{
|
||||
entry->Clear();
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
mozJSComponentLoader::UnloadModules()
|
||||
{
|
||||
@ -1384,7 +1389,8 @@ mozJSComponentLoader::UnloadModules()
|
||||
|
||||
mInProgressImports.Clear();
|
||||
mImports.Clear();
|
||||
mModules.Clear();
|
||||
|
||||
mModules.Enumerate(ClearModules, NULL);
|
||||
|
||||
// Destroying our context will force a GC.
|
||||
JS_DestroyContext(mContext);
|
||||
@ -1660,6 +1666,21 @@ mozJSComponentLoader::Observe(nsISupports *subject, const char *topic,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsIFactory>
|
||||
mozJSComponentLoader::ModuleEntry::GetFactory(const mozilla::Module& module,
|
||||
const mozilla::Module::CIDEntry& entry)
|
||||
{
|
||||
const ModuleEntry& self = static_cast<const ModuleEntry&>(module);
|
||||
NS_ASSERTION(self.getfactoryobj, "Handing out an uninitialized module?");
|
||||
|
||||
nsCOMPtr<nsIFactory> f;
|
||||
nsresult rv = self.getfactoryobj->Get(*entry.cid, getter_AddRefs(f));
|
||||
if (NS_FAILED(rv))
|
||||
return NULL;
|
||||
|
||||
return f.forget();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
JSCLContextHelper::JSCLContextHelper(mozJSComponentLoader *loader)
|
||||
|
@ -142,13 +142,24 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
||||
{
|
||||
public:
|
||||
ModuleEntry() : mozilla::Module() {
|
||||
|
||||
mVersion = mozilla::Module::kVersion;
|
||||
mCIDs = NULL;
|
||||
mContractIDs = NULL;
|
||||
mCategoryEntries = NULL;
|
||||
getfactory = GetFactory;
|
||||
loaded = NULL;
|
||||
unloaded = NULL;
|
||||
|
||||
global = nsnull;
|
||||
location = nsnull;
|
||||
}
|
||||
|
||||
~ModuleEntry() {
|
||||
getfactory = NULL;
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
getfactoryobj = NULL;
|
||||
|
||||
if (global) {
|
||||
JSAutoRequest ar(sSelf->mContext);
|
||||
@ -158,19 +169,25 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
||||
|
||||
if (location)
|
||||
NS_Free(location);
|
||||
|
||||
global = NULL;
|
||||
location = NULL;
|
||||
}
|
||||
|
||||
static already_AddRefed<nsIFactory> GetFactory(const mozilla::Module& module,
|
||||
const mozilla::Module::CIDEntry& entry);
|
||||
|
||||
nsCOMPtr<xpcIJSGetFactory> getfactory;
|
||||
nsCOMPtr<xpcIJSGetFactory> getfactoryobj;
|
||||
JSObject *global;
|
||||
char *location;
|
||||
};
|
||||
|
||||
friend class ModuleEntry;
|
||||
|
||||
nsClassHashtable<nsHashableHashKey, ModuleEntry> mModules;
|
||||
// Modules are intentionally leaked, but still cleared.
|
||||
static PLDHashOperator ClearModules(nsIHashable* key, ModuleEntry*& entry, void* cx);
|
||||
nsDataHashtable<nsHashableHashKey, ModuleEntry*> mModules;
|
||||
|
||||
nsClassHashtable<nsHashableHashKey, ModuleEntry> mImports;
|
||||
nsDataHashtable<nsHashableHashKey, ModuleEntry*> mInProgressImports;
|
||||
|
||||
|
@ -144,7 +144,6 @@ COMPONENT_LIBS += \
|
||||
webbrwsr \
|
||||
nsappshell \
|
||||
txmgr \
|
||||
chrome \
|
||||
commandlines \
|
||||
extensions \
|
||||
toolkitcomps \
|
||||
|
@ -252,7 +252,6 @@
|
||||
MODULE(appshell) \
|
||||
MODULE(nsTransactionManagerModule) \
|
||||
COMPOSER_MODULE \
|
||||
MODULE(nsChromeModule) \
|
||||
MODULE(application) \
|
||||
MODULE(Apprunner) \
|
||||
MODULE(CommandLineModule) \
|
||||
|
@ -200,7 +200,7 @@ endif
|
||||
# "toolkit" - xpfe & toolkit
|
||||
#
|
||||
|
||||
tier_platform_dirs += chrome profile
|
||||
tier_platform_dirs += profile
|
||||
|
||||
# This must preceed xpfe
|
||||
ifdef MOZ_JPROF
|
||||
|
@ -57,6 +57,7 @@ DIRS = \
|
||||
reflect \
|
||||
proxy \
|
||||
system \
|
||||
../chrome \
|
||||
build \
|
||||
$(NULL)
|
||||
|
||||
|
@ -82,6 +82,7 @@ CPPSRCS += Omnijar.cpp
|
||||
endif
|
||||
|
||||
SHARED_LIBRARY_LIBS = \
|
||||
$(DEPTH)/chrome/src/chrome_s.$(LIB_SUFFIX) \
|
||||
../ds/$(LIB_PREFIX)xpcomds_s.$(LIB_SUFFIX) \
|
||||
../io/$(LIB_PREFIX)xpcomio_s.$(LIB_SUFFIX) \
|
||||
../components/$(LIB_PREFIX)xpcomcomponents_s.$(LIB_SUFFIX) \
|
||||
@ -113,6 +114,7 @@ LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../threads/_xpidlgen \
|
||||
-I$(srcdir)/../proxy/src \
|
||||
-I$(srcdir)/../reflect/xptinfo/src \
|
||||
-I$(topsrcdir)/chrome/src \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla
|
||||
|
@ -306,5 +306,5 @@ void XXXNeverCalled()
|
||||
NS_WildCardMatch((const char *)nsnull, (const char *)nsnull, PR_FALSE);
|
||||
NS_WildCardMatch((const PRUnichar *)nsnull, (const PRUnichar *)nsnull, PR_FALSE);
|
||||
XRE_AddStaticComponent(NULL);
|
||||
XRE_AddComponentLocation(NULL);
|
||||
XRE_AddComponentLocation(NS_COMPONENT_LOCATION, NULL);
|
||||
}
|
||||
|
@ -143,6 +143,9 @@ extern nsresult nsStringInputStreamConstructor(nsISupports *, REFNSIID, void **)
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
|
||||
#include "nsChromeRegistry.h"
|
||||
#include "nsChromeProtocolHandler.h"
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
#include "base/at_exit.h"
|
||||
#include "base/command_line.h"
|
||||
@ -264,6 +267,12 @@ static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
|
||||
static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID);
|
||||
static NS_DEFINE_CID(kSimpleUnicharStreamFactoryCID, NS_SIMPLE_UNICHAR_STREAM_FACTORY_CID);
|
||||
|
||||
NS_DEFINE_NAMED_CID(NS_CHROMEREGISTRY_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CHROMEPROTOCOLHANDLER_CID);
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsChromeRegistry, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
|
||||
|
||||
#define NS_PERSISTENTPROPERTIES_CID NS_IPERSISTENTPROPERTIES_CID /* sigh */
|
||||
#define NS_XPCOMPROXY_CID NS_PROXYEVENT_MANAGER_CID
|
||||
|
||||
@ -293,6 +302,8 @@ const mozilla::Module::CIDEntry kXPCOMCIDEntries[] = {
|
||||
{ &kINIParserFactoryCID, false, CreateINIParserFactory },
|
||||
{ &kSimpleUnicharStreamFactoryCID, false, CreateUnicharStreamFactory },
|
||||
#include "XPCOMModule.inc"
|
||||
{ &kNS_CHROMEREGISTRY_CID, false, NULL, nsChromeRegistryConstructor },
|
||||
{ &kNS_CHROMEPROTOCOLHANDLER_CID, false, NULL, nsChromeProtocolHandlerConstructor },
|
||||
{ NULL }
|
||||
};
|
||||
#undef COMPONENT
|
||||
@ -300,6 +311,8 @@ const mozilla::Module::CIDEntry kXPCOMCIDEntries[] = {
|
||||
#define COMPONENT(NAME, Ctor) { NS_##NAME##_CONTRACTID, &kNS_##NAME##_CID },
|
||||
const mozilla::Module::ContractIDEntry kXPCOMContracts[] = {
|
||||
#include "XPCOMModule.inc"
|
||||
{ NS_CHROMEREGISTRY_CONTRACTID, &kNS_CHROMEREGISTRY_CID },
|
||||
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome", &kNS_CHROMEPROTOCOLHANDLER_CID },
|
||||
{ NULL }
|
||||
};
|
||||
#undef COMPONENT
|
||||
@ -473,25 +486,18 @@ NS_InitXPCOM2(nsIServiceManager* *result,
|
||||
NS_TIME_FUNCTION_MARK("Next: component manager init");
|
||||
|
||||
// Create the Component/Service Manager
|
||||
nsComponentManagerImpl *compMgr = new nsComponentManagerImpl();
|
||||
if (compMgr == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(compMgr);
|
||||
nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
|
||||
NS_ADDREF(nsComponentManagerImpl::gComponentManager);
|
||||
|
||||
rv = compMgr->Init();
|
||||
rv = nsComponentManagerImpl::gComponentManager->Init();
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
NS_RELEASE(compMgr);
|
||||
NS_RELEASE(nsComponentManagerImpl::gComponentManager);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsComponentManagerImpl::gComponentManager = compMgr;
|
||||
|
||||
if (result) {
|
||||
nsIServiceManager *serviceManager =
|
||||
static_cast<nsIServiceManager*>(compMgr);
|
||||
|
||||
NS_ADDREF(*result = serviceManager);
|
||||
NS_ADDREF(*result = nsComponentManagerImpl::gComponentManager);
|
||||
}
|
||||
|
||||
NS_TIME_FUNCTION_MARK("Next: cycle collector startup");
|
||||
|
@ -353,6 +353,7 @@ XRE_API(nsresult,
|
||||
*/
|
||||
XRE_API(nsresult,
|
||||
XRE_AddStaticComponent, (const mozilla::Module* aComponent))
|
||||
|
||||
/**
|
||||
* Register XPCOM components found in an array of files/directories.
|
||||
* This method may be called at any time before or after XRE_main or
|
||||
@ -361,9 +362,22 @@ XRE_API(nsresult,
|
||||
* @param aFiles An array of files or directories.
|
||||
* @param aFileCount the number of items in the aFiles array.
|
||||
* @note appdir/components is registered automatically.
|
||||
*
|
||||
* NS_COMPONENT_LOCATION specifies a location to search for binary XPCOM
|
||||
* components as well as component/chrome manifest files.
|
||||
*
|
||||
* NS_SKIN_LOCATION specifies a location to search for chrome manifest files
|
||||
* which are only allowed to register only skin packages and style overlays.
|
||||
*/
|
||||
enum NSLocationType
|
||||
{
|
||||
NS_COMPONENT_LOCATION,
|
||||
NS_SKIN_LOCATION
|
||||
};
|
||||
|
||||
XRE_API(nsresult,
|
||||
XRE_AddComponentLocation, (nsILocalFile* aLocation))
|
||||
XRE_AddComponentLocation, (NSLocationType aType,
|
||||
nsILocalFile* aLocation))
|
||||
|
||||
/**
|
||||
* Fire notifications to inform the toolkit about a new profile. This
|
||||
|
@ -46,6 +46,7 @@ MODULE = xpcom
|
||||
XPIDL_MODULE = xpcom_components
|
||||
LIBRARY_NAME = xpcomcomponents_s
|
||||
GRE_MODULE = 1
|
||||
LIBXUL_LIBRARY = 1
|
||||
MOZILLA_INTERNAL_API = 1
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla
|
||||
@ -64,6 +65,7 @@ EXPORTS_mozilla = \
|
||||
CPPSRCS = \
|
||||
nsCategoryManager.cpp \
|
||||
nsComponentManager.cpp \
|
||||
ManifestParser.cpp \
|
||||
nsNativeComponentLoader.cpp \
|
||||
GenericFactory.cpp \
|
||||
$(NULL)
|
||||
@ -84,6 +86,7 @@ LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../ds \
|
||||
-I$(srcdir)/../build \
|
||||
-I.. \
|
||||
-I$(topsrcdir)/chrome/src \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
|
472
xpcom/components/ManifestParser.cpp
Normal file
472
xpcom/components/ManifestParser.cpp
Normal file
@ -0,0 +1,472 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Firefox
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation <http://www.mozilla.org/>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ManifestParser.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "prio.h"
|
||||
#include "prprf.h"
|
||||
#if defined(XP_WIN)
|
||||
#include <windows.h>
|
||||
#elif defined(XP_MACOSX)
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#elif defined(MOZ_WIDGET_GTK2)
|
||||
#include <gtk/gtk.h>
|
||||
#endif
|
||||
|
||||
#include "nsTextFormatter.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsVersionComparator.h"
|
||||
#include "nsXPCOMCIDInternal.h"
|
||||
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIXULAppInfo.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
|
||||
struct ManifestDirective
|
||||
{
|
||||
const char* directive;
|
||||
int argc;
|
||||
|
||||
// Some directives should only be delivered for NS_COMPONENT_LOCATION
|
||||
// manifests.
|
||||
bool componentonly;
|
||||
|
||||
bool ischrome;
|
||||
|
||||
// The platform/contentaccessible flags only apply to content directives.
|
||||
bool contentflags;
|
||||
|
||||
// Function to handle this directive. This isn't a union because C++ still
|
||||
// hasn't learned how to initialize unions in a sane way.
|
||||
void (nsComponentManagerImpl::*mgrfunc)
|
||||
(nsComponentManagerImpl::ManifestProcessingContext& cx,
|
||||
int lineno, char *const * argv);
|
||||
void (nsChromeRegistry::*regfunc)
|
||||
(nsChromeRegistry::ManifestProcessingContext& cx,
|
||||
int lineno, char *const *argv,
|
||||
bool platform, bool contentaccessible);
|
||||
};
|
||||
static const ManifestDirective kParsingTable[] = {
|
||||
{ "binary-component", 1, true, false, false,
|
||||
&nsComponentManagerImpl::ManifestBinaryComponent, NULL },
|
||||
{ "component", 2, true, false, false,
|
||||
&nsComponentManagerImpl::ManifestComponent, NULL },
|
||||
{ "contract", 2, true, false, false,
|
||||
&nsComponentManagerImpl::ManifestContract, NULL },
|
||||
{ "category", 3, true, false, false,
|
||||
&nsComponentManagerImpl::ManifestCategory, NULL },
|
||||
{ "content", 2, true, true, true,
|
||||
NULL, &nsChromeRegistry::ManifestContent },
|
||||
{ "locale", 3, true, true, false,
|
||||
NULL, &nsChromeRegistry::ManifestLocale },
|
||||
{ "skin", 3, false, true, false,
|
||||
NULL, &nsChromeRegistry::ManifestSkin },
|
||||
{ "overlay", 2, true, true, false,
|
||||
NULL, &nsChromeRegistry::ManifestOverlay },
|
||||
{ "style", 2, false, true, false,
|
||||
NULL, &nsChromeRegistry::ManifestStyle },
|
||||
{ "override", 2, true, true, false,
|
||||
NULL, &nsChromeRegistry::ManifestOverride },
|
||||
{ "resource", 2, true, true, false,
|
||||
NULL, &nsChromeRegistry::ManifestResource }
|
||||
};
|
||||
|
||||
static const char kWhitespace[] = "\t ";
|
||||
static const char kNewlines[] = "\r\n";
|
||||
|
||||
static void LogMessageWithContext(nsILocalFile* aFile, PRUint32 aLineNumber, const char* aMsg, ...)
|
||||
{
|
||||
nsCOMPtr<nsIConsoleService> console =
|
||||
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
|
||||
nsCOMPtr<nsIScriptError> error =
|
||||
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
|
||||
if (!console || !error)
|
||||
return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, aMsg);
|
||||
char* formatted = PR_vsmprintf(aMsg, args);
|
||||
va_end(args);
|
||||
if (!formatted)
|
||||
return;
|
||||
|
||||
nsString file;
|
||||
aFile->GetPath(file);
|
||||
|
||||
nsresult rv = error->Init(NS_ConvertUTF8toUTF16(formatted).get(),
|
||||
file.get(), NULL,
|
||||
aLineNumber, 0, nsIScriptError::warningFlag,
|
||||
"chrome registration");
|
||||
PR_smprintf_free(formatted);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
console->LogMessage(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a modifier flag of the following forms:
|
||||
* "flag" (same as "true")
|
||||
* "flag=yes|true|1"
|
||||
* "flag="no|false|0"
|
||||
* @param aFlag The flag to compare.
|
||||
* @param aData The tokenized data to check; this is lowercased
|
||||
* before being passed in.
|
||||
* @param aResult If the flag is found, the value is assigned here.
|
||||
* @return Whether the flag was handled.
|
||||
*/
|
||||
static bool
|
||||
CheckFlag(const nsSubstring& aFlag, const nsSubstring& aData, bool& aResult)
|
||||
{
|
||||
if (!StringBeginsWith(aData, aFlag))
|
||||
return false;
|
||||
|
||||
if (aFlag.Length() == aData.Length()) {
|
||||
// the data is simply "flag", which is the same as "flag=yes"
|
||||
aResult = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aData.CharAt(aFlag.Length()) != '=') {
|
||||
// the data is "flag2=", which is not anything we care about
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aData.Length() == aFlag.Length() + 1) {
|
||||
aResult = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (aData.CharAt(aFlag.Length() + 1)) {
|
||||
case '1':
|
||||
case 't': //true
|
||||
case 'y': //yes
|
||||
aResult = true;
|
||||
return true;
|
||||
|
||||
case '0':
|
||||
case 'f': //false
|
||||
case 'n': //no
|
||||
aResult = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
enum TriState {
|
||||
eUnspecified,
|
||||
eBad,
|
||||
eOK
|
||||
};
|
||||
|
||||
/**
|
||||
* Check for a modifier flag of the following form:
|
||||
* "flag=string"
|
||||
* "flag!=string"
|
||||
* @param aFlag The flag to compare.
|
||||
* @param aData The tokenized data to check; this is lowercased
|
||||
* before being passed in.
|
||||
* @param aValue The value that is expected.
|
||||
* @param aResult If this is "ok" when passed in, this is left alone.
|
||||
* Otherwise if the flag is found it is set to eBad or eOK.
|
||||
* @return Whether the flag was handled.
|
||||
*/
|
||||
static bool
|
||||
CheckStringFlag(const nsSubstring& aFlag, const nsSubstring& aData,
|
||||
const nsSubstring& aValue, TriState& aResult)
|
||||
{
|
||||
if (aData.Length() < aFlag.Length() + 1)
|
||||
return false;
|
||||
|
||||
if (!StringBeginsWith(aData, aFlag))
|
||||
return false;
|
||||
|
||||
bool comparison = true;
|
||||
if (aData[aFlag.Length()] != '=') {
|
||||
if (aData[aFlag.Length()] == '!' &&
|
||||
aData.Length() >= aFlag.Length() + 2 &&
|
||||
aData[aFlag.Length() + 1] == '=')
|
||||
comparison = false;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aResult != eOK) {
|
||||
nsDependentSubstring testdata = Substring(aData, aFlag.Length() + (comparison ? 1 : 2));
|
||||
if (testdata.Equals(aValue))
|
||||
aResult = comparison ? eOK : eBad;
|
||||
else
|
||||
aResult = comparison ? eBad : eOK;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a modifier flag of the following form:
|
||||
* "flag=version"
|
||||
* "flag<=version"
|
||||
* "flag<version"
|
||||
* "flag>=version"
|
||||
* "flag>version"
|
||||
* @param aFlag The flag to compare.
|
||||
* @param aData The tokenized data to check; this is lowercased
|
||||
* before being passed in.
|
||||
* @param aValue The value that is expected. If this is empty then no
|
||||
* comparison will match.
|
||||
* @param aResult If this is eOK when passed in, this is left alone.
|
||||
* Otherwise if the flag is found it is set to eBad or eOK.
|
||||
* @return Whether the flag was handled.
|
||||
*/
|
||||
|
||||
#define COMPARE_EQ 1 << 0
|
||||
#define COMPARE_LT 1 << 1
|
||||
#define COMPARE_GT 1 << 2
|
||||
|
||||
static bool
|
||||
CheckVersionFlag(const nsString& aFlag, const nsString& aData,
|
||||
const nsString& aValue, TriState& aResult)
|
||||
{
|
||||
if (aData.Length() < aFlag.Length() + 2)
|
||||
return false;
|
||||
|
||||
if (!StringBeginsWith(aData, aFlag))
|
||||
return false;
|
||||
|
||||
if (aValue.Length() == 0) {
|
||||
if (aResult != eOK)
|
||||
aResult = eBad;
|
||||
return true;
|
||||
}
|
||||
|
||||
PRUint32 comparison;
|
||||
nsAutoString testdata;
|
||||
|
||||
switch (aData[aFlag.Length()]) {
|
||||
case '=':
|
||||
comparison = COMPARE_EQ;
|
||||
testdata = Substring(aData, aFlag.Length() + 1);
|
||||
break;
|
||||
|
||||
case '<':
|
||||
if (aData[aFlag.Length() + 1] == '=') {
|
||||
comparison = COMPARE_EQ | COMPARE_LT;
|
||||
testdata = Substring(aData, aFlag.Length() + 2);
|
||||
}
|
||||
else {
|
||||
comparison = COMPARE_LT;
|
||||
testdata = Substring(aData, aFlag.Length() + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if (aData[aFlag.Length() + 1] == '=') {
|
||||
comparison = COMPARE_EQ | COMPARE_GT;
|
||||
testdata = Substring(aData, aFlag.Length() + 2);
|
||||
}
|
||||
else {
|
||||
comparison = COMPARE_GT;
|
||||
testdata = Substring(aData, aFlag.Length() + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (testdata.Length() == 0)
|
||||
return false;
|
||||
|
||||
if (aResult != eOK) {
|
||||
PRInt32 c = NS_CompareVersions(aValue.get(), testdata.get());
|
||||
if ((c == 0 && comparison & COMPARE_EQ) ||
|
||||
(c < 0 && comparison & COMPARE_LT) ||
|
||||
(c > 0 && comparison & COMPARE_GT))
|
||||
aResult = eOK;
|
||||
else
|
||||
aResult = eBad;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsComponentManagerImpl::ManifestProcessingContext mgrcx(aType, aFile);
|
||||
nsChromeRegistry::ManifestProcessingContext chromecx(aType, aFile);
|
||||
|
||||
NS_NAMED_LITERAL_STRING(kPlatform, "platform");
|
||||
NS_NAMED_LITERAL_STRING(kContentAccessible, "contentaccessible");
|
||||
NS_NAMED_LITERAL_STRING(kApplication, "application");
|
||||
NS_NAMED_LITERAL_STRING(kAppVersion, "appversion");
|
||||
NS_NAMED_LITERAL_STRING(kOs, "os");
|
||||
NS_NAMED_LITERAL_STRING(kOsVersion, "osversion");
|
||||
|
||||
nsAutoString appID;
|
||||
nsAutoString appVersion;
|
||||
nsAutoString osTarget;
|
||||
nsCOMPtr<nsIXULAppInfo> xapp (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
|
||||
if (xapp) {
|
||||
nsCAutoString s;
|
||||
rv = xapp->GetID(s);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
CopyUTF8toUTF16(s, appID);
|
||||
|
||||
rv = xapp->GetVersion(s);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
CopyUTF8toUTF16(s, appVersion);
|
||||
|
||||
nsCOMPtr<nsIXULRuntime> xruntime (do_QueryInterface(xapp));
|
||||
if (xruntime) {
|
||||
rv = xruntime->GetOS(s);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
CopyUTF8toUTF16(s, osTarget);
|
||||
ToLowerCase(osTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString osVersion;
|
||||
#if defined(XP_WIN)
|
||||
OSVERSIONINFO info = { sizeof(OSVERSIONINFO) };
|
||||
if (GetVersionEx(&info)) {
|
||||
nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
|
||||
info.dwMajorVersion,
|
||||
info.dwMinorVersion);
|
||||
}
|
||||
#elif defined(XP_MACOSX)
|
||||
SInt32 majorVersion, minorVersion;
|
||||
if ((Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) &&
|
||||
(Gestalt(gestaltSystemVersionMinor, &minorVersion) == noErr)) {
|
||||
nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
|
||||
majorVersion,
|
||||
minorVersion);
|
||||
}
|
||||
#elif defined(MOZ_WIDGET_GTK2)
|
||||
nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
|
||||
gtk_major_version,
|
||||
gtk_minor_version);
|
||||
#endif
|
||||
|
||||
char *token;
|
||||
char *newline = buf;
|
||||
PRUint32 line = 0;
|
||||
|
||||
// outer loop tokenizes by newline
|
||||
while (nsnull != (token = nsCRT::strtok(newline, kNewlines, &newline))) {
|
||||
++line;
|
||||
|
||||
if (*token == '#') // ignore lines that begin with # as comments
|
||||
continue;
|
||||
|
||||
char *whitespace = token;
|
||||
token = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
|
||||
if (!token) continue;
|
||||
|
||||
const ManifestDirective* directive = NULL;
|
||||
for (const ManifestDirective* d = kParsingTable;
|
||||
d < kParsingTable + NS_ARRAY_LENGTH(kParsingTable);
|
||||
++d) {
|
||||
if (!strcmp(d->directive, token)) {
|
||||
directive = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!directive) {
|
||||
LogMessageWithContext(aFile, line, "Ignoring unrecognized chrome manifest directive '%s'.", token);
|
||||
continue;
|
||||
}
|
||||
if (directive->componentonly && NS_COMPONENT_LOCATION != aType) {
|
||||
LogMessageWithContext(aFile, line, "Skin manifest not allowed to use '%s' directive.", token);
|
||||
continue;
|
||||
}
|
||||
|
||||
NS_ASSERTION(directive->argc < 4, "Need to reset argv array length");
|
||||
char* argv[4];
|
||||
for (int i = 0; i < directive->argc; ++i)
|
||||
argv[i] = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
|
||||
|
||||
if (!argv[directive->argc - 1]) {
|
||||
LogMessageWithContext(aFile, line, "Not enough arguments for chrome manifest directive '%s', expected %i.", token, directive->argc);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
TriState stAppVersion = eUnspecified;
|
||||
TriState stApp = eUnspecified;
|
||||
TriState stOsVersion = eUnspecified;
|
||||
TriState stOs = eUnspecified;
|
||||
bool platform = false;
|
||||
bool contentAccessible = false;
|
||||
|
||||
while (NULL != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) && ok) {
|
||||
NS_ConvertASCIItoUTF16 wtoken(token);
|
||||
ToLowerCase(wtoken);
|
||||
|
||||
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
|
||||
CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
|
||||
CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) ||
|
||||
CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion))
|
||||
continue;
|
||||
|
||||
if (directive->contentflags &&
|
||||
(CheckFlag(kPlatform, wtoken, platform) ||
|
||||
CheckFlag(kContentAccessible, wtoken, contentAccessible)))
|
||||
continue;
|
||||
|
||||
LogMessageWithContext(aFile, line, "Unrecognized chrome manifest modifier '%s'.", token);
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if (!ok || stApp == eBad || stAppVersion == eBad || stOs == eBad || stOsVersion == eBad)
|
||||
continue;
|
||||
|
||||
if (directive->ischrome)
|
||||
(nsChromeRegistry::gChromeRegistry->*(directive->regfunc))
|
||||
(chromecx, line, argv, platform, contentAccessible);
|
||||
else
|
||||
(nsComponentManagerImpl::gComponentManager->*(directive->mgrfunc))
|
||||
(mgrcx, line, argv);
|
||||
}
|
||||
}
|
@ -1,73 +1,48 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIChromeRegistry.h"
|
||||
#include "nscore.h"
|
||||
#include "nsChromeProtocolHandler.h"
|
||||
#include "nsChromeRegistry.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsChromeRegistry, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
|
||||
|
||||
NS_DEFINE_NAMED_CID(NS_CHROMEREGISTRY_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CHROMEPROTOCOLHANDLER_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kChromeCIDs[] = {
|
||||
{ &kNS_CHROMEREGISTRY_CID, false, NULL, nsChromeRegistryConstructor },
|
||||
{ &kNS_CHROMEPROTOCOLHANDLER_CID, false, NULL, nsChromeProtocolHandlerConstructor },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const mozilla::Module::ContractIDEntry kChromeContracts[] = {
|
||||
{ NS_CHROMEREGISTRY_CONTRACTID, &kNS_CHROMEREGISTRY_CID },
|
||||
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome", &kNS_CHROMEPROTOCOLHANDLER_CID },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const mozilla::Module kChromeModule = {
|
||||
mozilla::Module::kVersion,
|
||||
kChromeCIDs,
|
||||
kChromeContracts
|
||||
};
|
||||
|
||||
NSMODULE_DEFN(nsChromeModule) = &kChromeModule;
|
||||
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Firefox
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation <http://www.mozilla.org/>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ManifestParser_h
|
||||
#define ManifestParser_h
|
||||
|
||||
#include "nsComponentManager.h"
|
||||
#include "nsChromeRegistry.h"
|
||||
|
||||
class nsILocalFile;
|
||||
|
||||
void ParseManifest(NSLocationType type, nsILocalFile* file, char* buf);
|
||||
|
||||
#endif // ManifestParser_h
|
@ -89,6 +89,7 @@
|
||||
#include "nsTArray.h"
|
||||
#include "prio.h"
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
#include "ManifestParser.h"
|
||||
|
||||
#include "nsInt64.h"
|
||||
#include "nsManifestLineReader.h"
|
||||
@ -313,7 +314,8 @@ nsComponentManagerImpl::InitializeStaticModules()
|
||||
sStaticModules->AppendElement(*staticModules);
|
||||
}
|
||||
|
||||
nsCOMArray<nsILocalFile>* nsComponentManagerImpl::sModuleLocations;
|
||||
nsTArray<nsComponentManagerImpl::ComponentLocation>*
|
||||
nsComponentManagerImpl::sModuleLocations;
|
||||
|
||||
/* static */ void
|
||||
nsComponentManagerImpl::InitializeModuleLocations()
|
||||
@ -321,7 +323,7 @@ nsComponentManagerImpl::InitializeModuleLocations()
|
||||
if (sModuleLocations)
|
||||
return;
|
||||
|
||||
sModuleLocations = new nsCOMArray<nsILocalFile>;
|
||||
sModuleLocations = new nsTArray<ComponentLocation>;
|
||||
}
|
||||
|
||||
nsresult nsComponentManagerImpl::Init()
|
||||
@ -341,6 +343,8 @@ nsresult nsComponentManagerImpl::Init()
|
||||
|
||||
mFactories.Init(CONTRACTID_HASHTABLE_INITIAL_SIZE);
|
||||
mContractIDs.Init(CONTRACTID_HASHTABLE_INITIAL_SIZE);
|
||||
mLoaderMap.Init();
|
||||
mKnownFileModules.Init();
|
||||
|
||||
mMon = nsAutoMonitor::NewMonitor("nsComponentManagerImpl");
|
||||
if (mMon == nsnull)
|
||||
@ -356,11 +360,17 @@ nsresult nsComponentManagerImpl::Init()
|
||||
InitializeStaticModules();
|
||||
InitializeModuleLocations();
|
||||
|
||||
ComponentLocation* l = sModuleLocations->InsertElementAt(0);
|
||||
l->type = NS_COMPONENT_LOCATION;
|
||||
l->location = appComponents;
|
||||
|
||||
PRBool equals = PR_FALSE;
|
||||
appComponents->Equals(greComponents, &equals);
|
||||
if (!equals)
|
||||
sModuleLocations->InsertObjectAt(greComponents, 0);
|
||||
sModuleLocations->InsertObjectAt(appComponents, 0);
|
||||
if (!equals) {
|
||||
l = sModuleLocations->InsertElementAt(0);
|
||||
l->type = NS_COMPONENT_LOCATION;
|
||||
l->location = greComponents;
|
||||
}
|
||||
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_DEBUG,
|
||||
("nsComponentManager: Initialized."));
|
||||
@ -377,8 +387,10 @@ nsresult nsComponentManagerImpl::Init()
|
||||
for (PRUint32 i = 0; i < sStaticModules->Length(); ++i)
|
||||
RegisterModule((*sStaticModules)[i], NULL);
|
||||
|
||||
for (PRInt32 i = 0; i < sModuleLocations->Count(); ++i)
|
||||
RegisterLocation((*sModuleLocations)[i]);
|
||||
for (PRUint32 i = 0; i < sModuleLocations->Length(); ++i) {
|
||||
ComponentLocation& l = sModuleLocations->ElementAt(i);
|
||||
RegisterLocation(l.type, l.location);
|
||||
}
|
||||
|
||||
nsCategoryManager::GetSingleton()->SuppressNotifications(false);
|
||||
|
||||
@ -394,7 +406,12 @@ nsComponentManagerImpl::RegisterModule(const mozilla::Module* aModule,
|
||||
nsAutoMonitor mon(mMon);
|
||||
|
||||
KnownModule* m = new KnownModule(aModule, aFile);
|
||||
mKnownModules.AppendElement(m);
|
||||
if (aFile) {
|
||||
nsCOMPtr<nsIHashable> h = do_QueryInterface(aFile);
|
||||
mKnownFileModules.Put(h, m);
|
||||
}
|
||||
else
|
||||
mKnownStaticModules.AppendElement(m);
|
||||
|
||||
if (aModule->mCIDs) {
|
||||
const mozilla::Module::CIDEntry* entry;
|
||||
@ -452,18 +469,26 @@ nsComponentManagerImpl::RegisterContractID(const mozilla::Module::ContractIDEntr
|
||||
}
|
||||
|
||||
void
|
||||
nsComponentManagerImpl::RegisterLocation(nsILocalFile* aLocation)
|
||||
nsComponentManagerImpl::RegisterLocation(NSLocationType aType,
|
||||
nsILocalFile* aLocation)
|
||||
{
|
||||
nsCOMArray<nsILocalFile> manifests;
|
||||
|
||||
PRBool directory = PR_FALSE;
|
||||
aLocation->IsDirectory(&directory);
|
||||
if (directory)
|
||||
RegisterDirectory(aLocation);
|
||||
RegisterDirectory(aType, aLocation, manifests);
|
||||
else
|
||||
RegisterFile(aLocation);
|
||||
RegisterFile(aType, aLocation, manifests);
|
||||
|
||||
for (PRInt32 i = 0; i < manifests.Count(); ++i)
|
||||
RegisterManifestFile(aType, manifests[i]);
|
||||
}
|
||||
|
||||
void
|
||||
nsComponentManagerImpl::RegisterDirectory(nsILocalFile* aDirectory)
|
||||
nsComponentManagerImpl::RegisterDirectory(NSLocationType aType,
|
||||
nsILocalFile* aDirectory,
|
||||
nsCOMArray<nsILocalFile>& aManifests)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
||||
aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
|
||||
@ -478,37 +503,224 @@ nsComponentManagerImpl::RegisterDirectory(nsILocalFile* aDirectory)
|
||||
if (!f)
|
||||
continue;
|
||||
|
||||
RegisterFile(f);
|
||||
RegisterFile(aType, f, aManifests);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsComponentManagerImpl::RegisterFile(nsILocalFile* aFile)
|
||||
static void
|
||||
GetExtension(nsILocalFile* file, nsCString& extension)
|
||||
{
|
||||
nsCString extension;
|
||||
aFile->GetNativePath(extension);
|
||||
file->GetNativePath(extension);
|
||||
|
||||
PRInt32 dotPos = extension.RFindChar('.');
|
||||
if (kNotFound == dotPos)
|
||||
extension.Truncate();
|
||||
else
|
||||
extension.Cut(0, dotPos + 1);
|
||||
}
|
||||
|
||||
void
|
||||
nsComponentManagerImpl::RegisterFile(NSLocationType aType,
|
||||
nsILocalFile* aFile,
|
||||
nsCOMArray<nsILocalFile>& aManifests)
|
||||
{
|
||||
nsCString extension;
|
||||
GetExtension(aFile, extension);
|
||||
|
||||
if (NS_COMPONENT_LOCATION == aType) {
|
||||
if (extension.EqualsLiteral("xpt")) {
|
||||
xptiInterfaceInfoManager::GetSingleton()
|
||||
->RegisterFile(aFile,
|
||||
xptiInterfaceInfoManager::XPT);
|
||||
}
|
||||
else if (extension.EqualsLiteral("jar")) {
|
||||
xptiInterfaceInfoManager::GetSingleton()
|
||||
->RegisterFile(aFile,
|
||||
xptiInterfaceInfoManager::ZIP);
|
||||
}
|
||||
}
|
||||
|
||||
if (extension.LowerCaseEqualsLiteral("manifest"))
|
||||
aManifests.AppendObject(aFile);
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct AutoCloseFD
|
||||
{
|
||||
AutoCloseFD()
|
||||
: mFD(NULL)
|
||||
{ }
|
||||
~AutoCloseFD() {
|
||||
if (mFD)
|
||||
PR_Close(mFD);
|
||||
}
|
||||
operator PRFileDesc*() {
|
||||
return mFD;
|
||||
}
|
||||
|
||||
PRFileDesc** operator&() {
|
||||
NS_ASSERTION(!mFD, "Re-opening a file");
|
||||
return &mFD;
|
||||
}
|
||||
|
||||
PRFileDesc* mFD;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void
|
||||
nsComponentManagerImpl::RegisterManifestFile(NSLocationType aType,
|
||||
nsILocalFile* aFile)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
AutoCloseFD fd;
|
||||
rv = aFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
extension.Cut(0, dotPos + 1);
|
||||
if (extension.LowerCaseEqualsLiteral(NAKED_DLL_SUFFIX)) {
|
||||
const mozilla::Module* m = mNativeModuleLoader.LoadModule(aFile);
|
||||
if (!m)
|
||||
PRFileInfo64 fileInfo;
|
||||
if (PR_SUCCESS != PR_GetOpenFileInfo64(fd, &fileInfo))
|
||||
return;
|
||||
|
||||
if (fileInfo.size > PRInt64(PR_INT32_MAX))
|
||||
return;
|
||||
|
||||
nsAutoArrayPtr<char> data(new char[PRInt32(fileInfo.size + 1)]);
|
||||
|
||||
for (PRInt32 totalRead = 0; totalRead < fileInfo.size; ) {
|
||||
PRInt32 read = PR_Read(fd, data + totalRead, PRInt32(fileInfo.size));
|
||||
if (read < 0)
|
||||
return;
|
||||
RegisterModule(m, aFile);
|
||||
totalRead += read;
|
||||
}
|
||||
else if (extension.EqualsLiteral("xpt")) {
|
||||
xptiInterfaceInfoManager::GetSingleton()
|
||||
->RegisterFile(aFile,
|
||||
xptiInterfaceInfoManager::XPT);
|
||||
|
||||
data[fileInfo.size] = '\0';
|
||||
ParseManifest(aType, aFile, data);
|
||||
}
|
||||
|
||||
void
|
||||
nsComponentManagerImpl::ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv)
|
||||
{
|
||||
char* file = argv[0];
|
||||
|
||||
nsCOMPtr<nsIFile> cfile;
|
||||
cx.mFile->GetParent(getter_AddRefs(cfile));
|
||||
nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
|
||||
|
||||
nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Couldn't append relative path?");
|
||||
return;
|
||||
}
|
||||
else if (extension.EqualsLiteral("jar")) {
|
||||
xptiInterfaceInfoManager::GetSingleton()
|
||||
->RegisterFile(aFile,
|
||||
xptiInterfaceInfoManager::ZIP);
|
||||
|
||||
const mozilla::Module* m = mNativeModuleLoader.LoadModule(clfile);
|
||||
if (!m) {
|
||||
// XXX report load error
|
||||
return;
|
||||
}
|
||||
RegisterModule(m, clfile);
|
||||
}
|
||||
|
||||
void
|
||||
nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& cx, int lineno, char *const * argv)
|
||||
{
|
||||
char* id = argv[0];
|
||||
char* file = argv[1];
|
||||
|
||||
nsID cid;
|
||||
if (!cid.Parse(id)) {
|
||||
// XXX report parse error
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoMonitor mon(mMon);
|
||||
nsFactoryEntry* f = mFactories.Get(cid);
|
||||
if (f) {
|
||||
// XXX report double-register error
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> cfile;
|
||||
cx.mFile->GetParent(getter_AddRefs(cfile));
|
||||
nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
|
||||
|
||||
nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Couldn't append relative path?");
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHashable> h = do_QueryInterface(clfile);
|
||||
KnownModule* km = mKnownFileModules.Get(h);
|
||||
if (!km) {
|
||||
km = new KnownModule(clfile);
|
||||
mKnownFileModules.Put(h, km);
|
||||
}
|
||||
|
||||
void* place;
|
||||
|
||||
PL_ARENA_ALLOCATE(place, &mArena, sizeof(nsCID));
|
||||
nsID* permanentCID = static_cast<nsID*>(place);
|
||||
*permanentCID = cid;
|
||||
|
||||
PL_ARENA_ALLOCATE(place, &mArena, sizeof(mozilla::Module::CIDEntry));
|
||||
mozilla::Module::CIDEntry* e = new (place) mozilla::Module::CIDEntry();
|
||||
e->cid = permanentCID;
|
||||
|
||||
f = new nsFactoryEntry(e, km);
|
||||
mFactories.Put(cid, f);
|
||||
}
|
||||
|
||||
void
|
||||
nsComponentManagerImpl::ManifestContract(ManifestProcessingContext& cx, int lineno, char *const * argv)
|
||||
{
|
||||
char* contract = argv[0];
|
||||
char* id = argv[1];
|
||||
|
||||
nsID cid;
|
||||
if (!cid.Parse(id)) {
|
||||
// XXX report parse error
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoMonitor mon(mMon);
|
||||
nsFactoryEntry* f = mFactories.Get(cid);
|
||||
if (!f) {
|
||||
// XXX report unregistered CID
|
||||
return;
|
||||
}
|
||||
|
||||
mContractIDs.Put(nsDependentCString(contract), f);
|
||||
}
|
||||
|
||||
void
|
||||
nsComponentManagerImpl::ManifestCategory(ManifestProcessingContext& cx, int lineno, char *const * argv)
|
||||
{
|
||||
char* category = argv[0];
|
||||
char* key = argv[1];
|
||||
char* value = argv[2];
|
||||
|
||||
nsCategoryManager::GetSingleton()->
|
||||
AddCategoryEntry(category, key, value);
|
||||
}
|
||||
|
||||
void
|
||||
nsComponentManagerImpl::RereadChromeManifests()
|
||||
{
|
||||
NS_ERROR("XXX Not done!");
|
||||
}
|
||||
|
||||
bool
|
||||
nsComponentManagerImpl::KnownModule::EnsureLoader()
|
||||
{
|
||||
if (!mLoader) {
|
||||
nsCString extension;
|
||||
GetExtension(mFile, extension);
|
||||
|
||||
mLoader = nsComponentManagerImpl::gComponentManager->LoaderForExtension(extension);
|
||||
}
|
||||
return !!mLoader;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -517,6 +729,8 @@ nsComponentManagerImpl::KnownModule::Load()
|
||||
if (mFailed)
|
||||
return false;
|
||||
if (!mModule) {
|
||||
if (!EnsureLoader())
|
||||
return false;
|
||||
mModule = mLoader->LoadModule(mFile);
|
||||
if (!mModule) {
|
||||
mFailed = true;
|
||||
@ -550,6 +764,8 @@ nsresult nsComponentManagerImpl::Shutdown(void)
|
||||
// Release all cached factories
|
||||
mContractIDs.Clear();
|
||||
mFactories.Clear(); // XXX release the objects, don't just clear
|
||||
mLoaderMap.Clear();
|
||||
mKnownFileModules.Clear();
|
||||
|
||||
mLoaderData.Clear();
|
||||
|
||||
@ -1244,16 +1460,6 @@ nsComponentManagerImpl::LoaderForExtension(const nsACString& aExt)
|
||||
return loader.forget();
|
||||
}
|
||||
|
||||
static void
|
||||
ReportLoadFailure(nsIFile* aFile, nsIConsoleService* aCS)
|
||||
{
|
||||
nsAutoString message;
|
||||
aFile->GetPath(message);
|
||||
message.Insert(NS_LITERAL_STRING("Failed to load XPCOM component: "), 0);
|
||||
|
||||
aCS->LogStringMessage(message.get());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComponentManagerImpl::RegisterFactory(const nsCID& aClass,
|
||||
const char* aName,
|
||||
@ -1418,7 +1624,7 @@ nsFactoryEntry::GetFactory()
|
||||
mFactory = mModule->Module()->getfactory(*mModule->Module(),
|
||||
*mCIDEntry);
|
||||
}
|
||||
if (mCIDEntry->getfactory) {
|
||||
else if (mCIDEntry->getfactory) {
|
||||
mFactory = mCIDEntry->getfactory(*mModule->Module(), *mCIDEntry);
|
||||
}
|
||||
else {
|
||||
@ -1481,14 +1687,17 @@ XRE_AddStaticComponent(const mozilla::Module* aComponent)
|
||||
}
|
||||
|
||||
EXPORT_XPCOM_API(nsresult)
|
||||
XRE_AddComponentLocation(nsILocalFile* aLocation)
|
||||
XRE_AddComponentLocation(NSLocationType aType, nsILocalFile* aLocation)
|
||||
{
|
||||
nsComponentManagerImpl::InitializeModuleLocations();
|
||||
nsComponentManagerImpl::sModuleLocations->AppendObject(aLocation);
|
||||
nsComponentManagerImpl::ComponentLocation* c =
|
||||
nsComponentManagerImpl::sModuleLocations->AppendElement();
|
||||
c->type = aType;
|
||||
c->location = aLocation;
|
||||
|
||||
if (nsComponentManagerImpl::gComponentManager &&
|
||||
nsComponentManagerImpl::NORMAL == nsComponentManagerImpl::gComponentManager->mStatus)
|
||||
nsComponentManagerImpl::gComponentManager->RegisterLocation(aLocation);
|
||||
nsComponentManagerImpl::gComponentManager->RegisterLocation(aType, aLocation);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "nsILocalFile.h"
|
||||
#include "mozilla/Module.h"
|
||||
#include "mozilla/ModuleLoader.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsNativeComponentLoader.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
@ -62,6 +63,7 @@
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
struct nsFactoryEntry;
|
||||
@ -157,8 +159,14 @@ public:
|
||||
static void InitializeStaticModules();
|
||||
static void InitializeModuleLocations();
|
||||
|
||||
struct ComponentLocation
|
||||
{
|
||||
NSLocationType type;
|
||||
nsCOMPtr<nsILocalFile> location;
|
||||
};
|
||||
|
||||
static nsTArray<const mozilla::Module*>* sStaticModules;
|
||||
static nsCOMArray<nsILocalFile>* sModuleLocations;
|
||||
static nsTArray<ComponentLocation>* sModuleLocations;
|
||||
|
||||
nsNativeModuleLoader mNativeModuleLoader;
|
||||
|
||||
@ -175,10 +183,10 @@ public:
|
||||
, mFailed(false)
|
||||
{ }
|
||||
|
||||
KnownModule(nsILocalFile* aFile, mozilla::ModuleLoader* aLoader)
|
||||
KnownModule(nsILocalFile* aFile)
|
||||
: mModule(NULL)
|
||||
, mFile(aFile)
|
||||
, mLoader(aLoader)
|
||||
, mLoader(NULL)
|
||||
, mLoaded(false)
|
||||
, mFailed(false)
|
||||
{ }
|
||||
@ -189,6 +197,7 @@ public:
|
||||
mModule->unloaded();
|
||||
}
|
||||
|
||||
bool EnsureLoader();
|
||||
bool Load();
|
||||
|
||||
const mozilla::Module* Module() const
|
||||
@ -204,7 +213,10 @@ public:
|
||||
bool mFailed;
|
||||
};
|
||||
|
||||
nsTArray< nsAutoPtr<KnownModule> > mKnownModules;
|
||||
// The KnownModule is kept alive by these members, it is referenced by pointer
|
||||
// from the factory entries.
|
||||
nsTArray< nsAutoPtr<KnownModule> > mKnownStaticModules;
|
||||
nsClassHashtable<nsHashableHashKey, KnownModule> mKnownFileModules;
|
||||
|
||||
void RegisterModule(const mozilla::Module* aModule,
|
||||
nsILocalFile* aFile);
|
||||
@ -212,9 +224,36 @@ public:
|
||||
KnownModule* aModule);
|
||||
void RegisterContractID(const mozilla::Module::ContractIDEntry* aEntry);
|
||||
|
||||
void RegisterLocation(nsILocalFile* aLocation);
|
||||
void RegisterDirectory(nsILocalFile* aDirectory);
|
||||
void RegisterFile(nsILocalFile* aFile);
|
||||
void RegisterLocation(NSLocationType aType, nsILocalFile* aLocation);
|
||||
|
||||
// Register XPT/XPTJAR files, and fills aManifests with .manifest
|
||||
// files, which must be registered after all DLLs so that networking is
|
||||
// registered.
|
||||
void RegisterDirectory(NSLocationType aType, nsILocalFile* aDirectory,
|
||||
nsCOMArray<nsILocalFile>& aManifests);
|
||||
void RegisterFile(NSLocationType aType, nsILocalFile* aFile,
|
||||
nsCOMArray<nsILocalFile>& aManifests);
|
||||
|
||||
void RegisterManifestFile(NSLocationType aType, nsILocalFile* aFile);
|
||||
|
||||
struct ManifestProcessingContext
|
||||
{
|
||||
ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile)
|
||||
: mType(aType)
|
||||
, mFile(aFile)
|
||||
{ }
|
||||
~ManifestProcessingContext() { }
|
||||
|
||||
NSLocationType mType;
|
||||
nsCOMPtr<nsILocalFile> mFile;
|
||||
};
|
||||
|
||||
void ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv);
|
||||
void ManifestComponent(ManifestProcessingContext& cx, int lineno, char *const * argv);
|
||||
void ManifestContract(ManifestProcessingContext& cx, int lineno, char* const * argv);
|
||||
void ManifestCategory(ManifestProcessingContext& cx, int lineno, char* const * argv);
|
||||
|
||||
void RereadChromeManifests();
|
||||
|
||||
// Shutdown
|
||||
enum {
|
||||
|
@ -63,6 +63,12 @@ public:
|
||||
* @param pData if the key doesn't exist, pData will be set to nsnull.
|
||||
*/
|
||||
PRBool Get(KeyType aKey, UserDataType* pData) const;
|
||||
|
||||
/**
|
||||
* @copydoc nsBaseHashtable::Get
|
||||
* @returns NULL if the key is not present.
|
||||
*/
|
||||
UserDataType Get(KeyType aKey) const;
|
||||
};
|
||||
|
||||
|
||||
@ -114,6 +120,19 @@ nsClassHashtable<KeyClass,T>::Get(KeyType aKey, T** retVal) const
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
template<class KeyClass,class T>
|
||||
T*
|
||||
nsClassHashtable<KeyClass,T>::Get(KeyType aKey) const
|
||||
{
|
||||
typename nsBaseHashtable<KeyClass,nsAutoPtr<T>,T*>::EntryType* ent =
|
||||
GetEntry(aKey);
|
||||
|
||||
if (!ent)
|
||||
return NULL;
|
||||
|
||||
return ent->mData;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// nsClassHashtableMT definitions
|
||||
|
@ -109,3 +109,8 @@ libs:: $(TARGETS)
|
||||
install:: $(TARGETS)
|
||||
$(SYSINSTALL) $(IFLAGS1) $(srcdir)/xpconnect-sample.html $(DESTDIR)$(mozappdir)/res/samples
|
||||
|
||||
# XXX TEMPORARY DEMONSTRATION HACK
|
||||
libs::
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(srcdir)/nsSample.manifest > $(DIST)/bin/components/nsSample.manifest
|
||||
|
||||
DEFINES += -DSHARED_LIBRARY=$(SHARED_LIBRARY)
|
||||
|
@ -40,90 +40,30 @@ mySample.prototype = {
|
||||
},
|
||||
|
||||
val: "<default value>"
|
||||
}
|
||||
|
||||
var myModule = {
|
||||
firstTime: true,
|
||||
|
||||
/*
|
||||
* RegisterSelf is called at registration time (component installation
|
||||
* or the only-until-release startup autoregistration) and is responsible
|
||||
* for notifying the component manager of all components implemented in
|
||||
* this module. The fileSpec, location and type parameters are mostly
|
||||
* opaque, and should be passed on to the registerComponent call
|
||||
* unmolested.
|
||||
*/
|
||||
registerSelf: function (compMgr, fileSpec, location, type) {
|
||||
if (this.firstTime) {
|
||||
debug("*** Deferring registration of sample JS components\n");
|
||||
this.firstTime = false;
|
||||
throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
|
||||
}
|
||||
debug("*** Registering sample JS components\n");
|
||||
compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
|
||||
compMgr.registerFactoryLocation(this.myCID,
|
||||
"Sample JS Component",
|
||||
this.myProgID,
|
||||
fileSpec,
|
||||
location,
|
||||
type);
|
||||
},
|
||||
|
||||
/*
|
||||
* The GetClassObject method is responsible for producing Factory objects
|
||||
*/
|
||||
getClassObject: function (compMgr, cid, iid) {
|
||||
if (!cid.equals(this.myCID))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
|
||||
if (!iid.equals(Components.interfaces.nsIFactory))
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
return this.myFactory;
|
||||
},
|
||||
|
||||
/* CID for this class */
|
||||
myCID: Components.ID("{dea98e50-1dd1-11b2-9344-8902b4805a2e}"),
|
||||
|
||||
/* ProgID for this class */
|
||||
myProgID: "@mozilla.org/jssample;1",
|
||||
|
||||
/* factory object */
|
||||
myFactory: {
|
||||
/*
|
||||
* Construct an instance of the interface specified by iid, possibly
|
||||
* aggregating it with the provided outer. (If you don't know what
|
||||
* aggregation is all about, you don't need to. It reduces even the
|
||||
* mightiest of XPCOM warriors to snivelling cowards.)
|
||||
*/
|
||||
createInstance: function (outer, iid) {
|
||||
debug("CI: " + iid + "\n");
|
||||
if (outer != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
return (new mySample()).QueryInterface(iid);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* The canUnload method signals that the component is about to be unloaded.
|
||||
* C++ components can return false to indicate that they don't wish to be
|
||||
* unloaded, but the return value from JS components' canUnload is ignored:
|
||||
* mark-and-sweep will keep everything around until it's no longer in use,
|
||||
* making unconditional ``unload'' safe.
|
||||
*
|
||||
* You still need to provide a (likely useless) canUnload method, though:
|
||||
* it's part of the nsIModule interface contract, and the JS loader _will_
|
||||
* call it.
|
||||
*/
|
||||
canUnload: function(compMgr) {
|
||||
debug("*** Unloading sample JS components\n");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
function NSGetModule(compMgr, fileSpec) {
|
||||
return myModule;
|
||||
const kMyCID = Components.ID("{dea98e50-1dd1-11b2-9344-8902b4805a2e}");
|
||||
|
||||
const kMyFactory = {
|
||||
/*
|
||||
* Construct an instance of the interface specified by iid, possibly
|
||||
* aggregating it with the provided outer. (If you don't know what
|
||||
* aggregation is all about, you don't need to. It reduces even the
|
||||
* mightiest of XPCOM warriors to snivelling cowards.)
|
||||
*/
|
||||
createInstance: function (outer, iid) {
|
||||
debug("CI: " + iid + "\n");
|
||||
if (outer != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
return (new mySample()).QueryInterface(iid);
|
||||
}
|
||||
};
|
||||
|
||||
function NSGetFactory(cid)
|
||||
{
|
||||
if (cid.equals(kMyCID))
|
||||
return kMyFactory;
|
||||
|
||||
throw Components.results.NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
}
|
||||
|
||||
|
||||
|
3
xpcom/sample/nsSample.manifest
Normal file
3
xpcom/sample/nsSample.manifest
Normal file
@ -0,0 +1,3 @@
|
||||
component dea98e50-1dd1-11b2-9344-8902b4805a2e nsSample.js
|
||||
contract @mozilla.org/jssample;1 dea98e50-1dd1-11b2-9344-8902b4805a2e
|
||||
binary-component @SHARED_LIBRARY@
|
@ -161,8 +161,10 @@ int main(int argc, char** argv)
|
||||
|
||||
|
||||
const char *regPath = argv[1];
|
||||
XRE_AddComponentLocation(nsCOMPtr<nsILocalFile>(GetRegDirectory(regPath, "core")));
|
||||
XRE_AddComponentLocation(nsCOMPtr<nsILocalFile>(GetRegDirectory(regPath, "extension")));
|
||||
XRE_AddComponentLocation(NS_COMPONENT_LOCATION,
|
||||
nsCOMPtr<nsILocalFile>(GetRegDirectory(regPath, "core")));
|
||||
XRE_AddComponentLocation(NS_COMPONENT_LOCATION,
|
||||
nsCOMPtr<nsILocalFile>(GetRegDirectory(regPath, "extension")));
|
||||
ScopedXPCOM xpcom("RegistrationOrder");
|
||||
if (xpcom.failed())
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user