mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 23:35:34 +00:00
Bug 1524688: Part 1a - Support static registration JS components. r=mccr8
--HG-- extra : source : 68eb174a337b20e64583ae8afd45d479a3f54b61
This commit is contained in:
parent
b718cffa0e
commit
a34d453ee8
@ -102,6 +102,12 @@ Class definitions may have the following properties:
|
||||
|
||||
This property is incompatible with ``legacy_constructor``.
|
||||
|
||||
``jsm`` (optional)
|
||||
If provided, must be the URL of a JavaScript module which contains a
|
||||
JavaScript implementation of the component. The ``constructor`` property
|
||||
must contain the name of an exported function which can be constructed to
|
||||
create a new instance of the component.
|
||||
|
||||
``legacy_constructor`` (optional)
|
||||
This property is deprecated, and should not be used in new code.
|
||||
|
||||
|
@ -9,8 +9,11 @@
|
||||
#include "mozilla/PerfectHash.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozJSComponentLoader.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsComponentManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsString.h"
|
||||
@ -27,6 +30,9 @@
|
||||
//# @decls@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using dom::AutoJSAPI;
|
||||
|
||||
namespace xpcom {
|
||||
|
||||
static constexpr uint32_t kNoContractID = 0xffffffff;
|
||||
@ -83,6 +89,37 @@ bool ContractEntry::Matches(const nsACString& aContractID) const {
|
||||
}
|
||||
|
||||
|
||||
static nsresult ConstructJSMComponent(const nsACString& aURI,
|
||||
const char* aConstructor,
|
||||
nsISupports** aResult) {
|
||||
if (!nsComponentManagerImpl::JSLoaderReady()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope()));
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
JS::RootedObject global(cx);
|
||||
JS::RootedObject exports(cx);
|
||||
MOZ_TRY(mozJSComponentLoader::Get()->Import(cx, aURI, &global, &exports));
|
||||
|
||||
JS::RootedValue ctor(cx);
|
||||
if (!JS_GetProperty(cx, exports, aConstructor, &ctor) ||
|
||||
!ctor.isObject()) {
|
||||
return NS_ERROR_XPC_JSOBJECT_HAS_NO_FUNCTION_NAMED;
|
||||
}
|
||||
|
||||
JS::RootedObject inst(cx);
|
||||
if (!JS::Construct(cx, ctor, JS::HandleValueArray::empty(), &inst)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return nsContentUtils::XPConnect()->WrapJS(cx, inst, NS_GET_IID(nsISupports),
|
||||
(void**)aResult);
|
||||
}
|
||||
|
||||
|
||||
//# @module_cid_table@
|
||||
|
||||
//# @module_contract_id_table@
|
||||
|
@ -218,6 +218,8 @@ class ModuleEntry(object):
|
||||
self.legacy_constructor = data.get('legacy_constructor', None)
|
||||
self.init_method = data.get('init_method', [])
|
||||
|
||||
self.jsm = data.get('jsm', None)
|
||||
|
||||
self.external = data.get('external', not (self.headers or
|
||||
self.legacy_constructor))
|
||||
self.singleton = data.get('singleton', False)
|
||||
@ -236,7 +238,15 @@ class ModuleEntry(object):
|
||||
str(self.cid), ', '.join(map(repr, self.contract_ids)),
|
||||
str_))
|
||||
|
||||
if self.external:
|
||||
if self.jsm:
|
||||
if not self.constructor:
|
||||
error("JavaScript components must specify a constructor")
|
||||
|
||||
for prop in ('init_method', 'legacy_constructor', 'headers'):
|
||||
if getattr(self, prop):
|
||||
error("JavaScript components may not specify a '%s' "
|
||||
"property" % prop)
|
||||
elif self.external:
|
||||
if self.constructor or self.legacy_constructor:
|
||||
error("Externally-constructed components may not specify "
|
||||
"'constructor' or 'legacy_constructor' properties")
|
||||
@ -299,7 +309,14 @@ class ModuleEntry(object):
|
||||
% self.legacy_constructor)
|
||||
return res
|
||||
|
||||
if self.external:
|
||||
if self.jsm:
|
||||
res += (
|
||||
' nsCOMPtr<nsISupports> inst;\n'
|
||||
' MOZ_TRY(ConstructJSMComponent(NS_LITERAL_CSTRING(%s),\n'
|
||||
' %s,\n'
|
||||
' getter_AddRefs(inst)));'
|
||||
'\n' % (json.dumps(self.jsm), json.dumps(self.constructor)))
|
||||
elif self.external:
|
||||
res += (' nsCOMPtr<nsISupports> inst = '
|
||||
'mozCreateComponent<%s>();\n' % self.type)
|
||||
else:
|
||||
|
@ -531,6 +531,8 @@ nsresult nsComponentManagerImpl::Init() {
|
||||
// used, and before any calls are made into the JS engine.
|
||||
nsLayoutModuleInitialize();
|
||||
|
||||
mJSLoaderReady = true;
|
||||
|
||||
// The overall order in which chrome.manifests are expected to be treated
|
||||
// is the following:
|
||||
// - greDir
|
||||
|
@ -166,6 +166,8 @@ class nsComponentManagerImpl final : public nsIComponentManager,
|
||||
nsresult GetService(mozilla::xpcom::ModuleID, const nsIID& aIID,
|
||||
void** aResult);
|
||||
|
||||
static bool JSLoaderReady() { return gComponentManager->mJSLoaderReady; }
|
||||
|
||||
static void InitializeStaticModules();
|
||||
static void InitializeModuleLocations();
|
||||
|
||||
@ -281,6 +283,8 @@ class nsComponentManagerImpl final : public nsIComponentManager,
|
||||
|
||||
nsTArray<PendingServiceInfo> mPendingServices;
|
||||
|
||||
bool mJSLoaderReady = false;
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user