зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1769002 - Support ESM in components.conf. r=kmag
Also ESM-ify SimpleServices.jsm as an example, given an empty array is not allowed inside StaticComponents.cpp. Differential Revision: https://phabricator.services.mozilla.com/D147414
This commit is contained in:
Родитель
3d15caadb4
Коммит
591472f193
|
@ -832,6 +832,7 @@ add_task(async function checkAllTheFiles() {
|
|||
".mjs",
|
||||
".js",
|
||||
".jsm",
|
||||
".mjs",
|
||||
".json",
|
||||
".html",
|
||||
".xhtml",
|
||||
|
@ -880,6 +881,9 @@ add_task(async function checkAllTheFiles() {
|
|||
for (let jsm of Components.manager.getComponentJSMs()) {
|
||||
gReferencesFromCode.set(jsm, null);
|
||||
}
|
||||
for (let esModule of Components.manager.getComponentESModules()) {
|
||||
gReferencesFromCode.set(esModule, null);
|
||||
}
|
||||
|
||||
// manifest.json is a common name, it is used for WebExtension manifests
|
||||
// but also for other things. To tell them apart, we have to actually
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
/* globals WebExtensionPolicy */
|
||||
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
@ -25,7 +26,6 @@ ChromeUtils.defineModuleGetter(
|
|||
"NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
lazy,
|
||||
|
@ -46,7 +46,7 @@ const ArrayBufferInputStream = Components.Constructor(
|
|||
* See SubstituteChannel in netwerk/protocol/res/ExtensionProtocolHandler.cpp
|
||||
* for usage.
|
||||
*/
|
||||
function AddonLocalizationConverter() {}
|
||||
export function AddonLocalizationConverter() {}
|
||||
|
||||
AddonLocalizationConverter.prototype = {
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIStreamConverter"]),
|
||||
|
@ -137,7 +137,7 @@ AddonLocalizationConverter.prototype = {
|
|||
},
|
||||
};
|
||||
|
||||
function HttpIndexViewer() {}
|
||||
export function HttpIndexViewer() {}
|
||||
|
||||
HttpIndexViewer.prototype = {
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIDocumentLoaderFactory"]),
|
||||
|
@ -180,5 +180,3 @@ HttpIndexViewer.prototype = {
|
|||
return res;
|
||||
},
|
||||
};
|
||||
|
||||
var EXPORTED_SYMBOLS = ["AddonLocalizationConverter", "HttpIndexViewer"];
|
|
@ -8,13 +8,13 @@ Classes = [
|
|||
{
|
||||
'cid': '{ded150e3-c92e-4077-a396-0dba9953e39f}',
|
||||
'contract_ids': ['@mozilla.org/streamconv;1?from=application/vnd.mozilla.webext.unlocalized&to=text/css'],
|
||||
'jsm': 'resource://gre/modules/SimpleServices.jsm',
|
||||
'esModule': 'resource://gre/modules/SimpleServices.sys.mjs',
|
||||
'constructor': 'AddonLocalizationConverter',
|
||||
},
|
||||
{
|
||||
'cid': '{742ad274-34c5-43d1-a8b7-293eaf8962d6}',
|
||||
'contract_ids': ['@mozilla.org/content-viewers/http-index-format'],
|
||||
'jsm': 'resource://gre/modules/SimpleServices.jsm',
|
||||
'esModule': 'resource://gre/modules/SimpleServices.sys.mjs',
|
||||
'constructor': 'HttpIndexViewer',
|
||||
'categories': {'Gecko-Content-Viewers': 'application/http-index-format'},
|
||||
},
|
||||
|
|
|
@ -8,7 +8,7 @@ with Files("**"):
|
|||
BUG_COMPONENT = ("Toolkit", "General")
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
"SimpleServices.jsm",
|
||||
"SimpleServices.sys.mjs",
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES["components-utils"] = [
|
||||
|
|
|
@ -87,6 +87,10 @@ const StringOffset gComponentJSMs[] = {
|
|||
//# @component_jsms@
|
||||
};
|
||||
|
||||
const StringOffset gComponentESModules[] = {
|
||||
//# @component_esmodules@
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a nsCString corresponding to the given entry in the `gStrings` string
|
||||
* table. The resulting nsCString points directly to static storage, and does
|
||||
|
@ -107,10 +111,12 @@ bool ContractEntry::Matches(const nsACString& aContractID) const {
|
|||
return aContractID == ContractID() && Module().Active();
|
||||
}
|
||||
|
||||
enum class ComponentType { JSM, ESM };
|
||||
|
||||
static nsresult ConstructJSMComponent(const nsACString& aURI,
|
||||
const char* aConstructor,
|
||||
nsISupports** aResult) {
|
||||
template <ComponentType type>
|
||||
static nsresult ConstructJSMOrESMComponent(const nsACString& aURI,
|
||||
const char* aConstructor,
|
||||
nsISupports** aResult) {
|
||||
if (!nsComponentManagerImpl::JSLoaderReady()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
@ -119,17 +125,21 @@ static nsresult ConstructJSMComponent(const nsACString& aURI,
|
|||
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::Rooted<JSObject*> exports(cx);
|
||||
if constexpr (type == ComponentType::JSM) {
|
||||
JS::Rooted<JSObject*> global(cx);
|
||||
MOZ_TRY(mozJSComponentLoader::Get()->Import(cx, aURI, &global, &exports));
|
||||
} else {
|
||||
MOZ_TRY(mozJSComponentLoader::Get()->ImportESModule(cx, aURI, &exports));
|
||||
}
|
||||
|
||||
JS::RootedValue ctor(cx);
|
||||
JS::Rooted<JS::Value> ctor(cx);
|
||||
if (!JS_GetProperty(cx, exports, aConstructor, &ctor) ||
|
||||
!ctor.isObject()) {
|
||||
return NS_ERROR_XPC_JSOBJECT_HAS_NO_FUNCTION_NAMED;
|
||||
}
|
||||
|
||||
JS::RootedObject inst(cx);
|
||||
JS::Rooted<JSObject*> inst(cx);
|
||||
if (!JS::Construct(cx, ctor, JS::HandleValueArray::empty(), &inst)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -138,6 +148,19 @@ static nsresult ConstructJSMComponent(const nsACString& aURI,
|
|||
(void**)aResult);
|
||||
}
|
||||
|
||||
static nsresult ConstructJSMComponent(const nsACString& aURI,
|
||||
const char* aConstructor,
|
||||
nsISupports** aResult) {
|
||||
return ConstructJSMOrESMComponent<ComponentType::JSM>(
|
||||
aURI, aConstructor, aResult);
|
||||
}
|
||||
|
||||
static nsresult ConstructESModuleComponent(const nsACString& aURI,
|
||||
const char* aConstructor,
|
||||
nsISupports** aResult) {
|
||||
return ConstructJSMOrESMComponent<ComponentType::ESM>(
|
||||
aURI, aConstructor, aResult);
|
||||
}
|
||||
|
||||
//# @module_cid_table@
|
||||
|
||||
|
@ -330,6 +353,20 @@ StaticComponents::GetComponentJSMs() {
|
|||
return result.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsIUTF8StringEnumerator>
|
||||
StaticComponents::GetComponentESModules() {
|
||||
auto esModules = MakeUnique<nsTArray<nsCString>>(MOZ_ARRAY_LENGTH(gComponentESModules));
|
||||
|
||||
for (const auto& entry : gComponentESModules) {
|
||||
esModules->AppendElement(GetString(entry));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIUTF8StringEnumerator> result;
|
||||
MOZ_ALWAYS_SUCCEEDS(NS_NewAdoptingUTF8StringEnumerator(getter_AddRefs(result),
|
||||
esModules.release()));
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
/* static */ Span<const JSServiceEntry> StaticComponents::GetJSServices() {
|
||||
return { gJSServices, ArrayLength(gJSServices) };
|
||||
}
|
||||
|
|
|
@ -243,6 +243,7 @@ class StaticComponents final {
|
|||
bool aInvalid = true);
|
||||
|
||||
static already_AddRefed<nsIUTF8StringEnumerator> GetComponentJSMs();
|
||||
static already_AddRefed<nsIUTF8StringEnumerator> GetComponentESModules();
|
||||
|
||||
static Span<const JSServiceEntry> GetJSServices();
|
||||
|
||||
|
|
|
@ -282,6 +282,7 @@ class ModuleEntry(object):
|
|||
self.init_method = data.get("init_method", [])
|
||||
|
||||
self.jsm = data.get("jsm", None)
|
||||
self.esModule = data.get("esModule", None)
|
||||
|
||||
self.external = data.get(
|
||||
"external", not (self.headers or self.legacy_constructor)
|
||||
|
@ -307,6 +308,16 @@ class ModuleEntry(object):
|
|||
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.esModule:
|
||||
if not self.constructor:
|
||||
error("JavaScript components must specify a constructor")
|
||||
|
||||
for prop in ("init_method", "legacy_constructor", "headers"):
|
||||
if getattr(self, prop):
|
||||
error(
|
||||
|
@ -413,6 +424,14 @@ class ModuleEntry(object):
|
|||
" getter_AddRefs(inst)));"
|
||||
"\n" % (json.dumps(self.jsm), json.dumps(self.constructor))
|
||||
)
|
||||
elif self.esModule:
|
||||
res += (
|
||||
" nsCOMPtr<nsISupports> inst;\n"
|
||||
" MOZ_TRY(ConstructESModuleComponent(nsLiteralCString(%s),\n"
|
||||
" %s,\n"
|
||||
" getter_AddRefs(inst)));"
|
||||
"\n" % (json.dumps(self.esModule), json.dumps(self.constructor))
|
||||
)
|
||||
elif self.external:
|
||||
res += (
|
||||
" nsCOMPtr<nsISupports> inst = "
|
||||
|
@ -743,6 +762,7 @@ def gen_substs(manifests):
|
|||
js_services = {}
|
||||
|
||||
jsms = set()
|
||||
esModules = set()
|
||||
|
||||
types = set()
|
||||
|
||||
|
@ -767,6 +787,9 @@ def gen_substs(manifests):
|
|||
if mod.jsm:
|
||||
jsms.add(mod.jsm)
|
||||
|
||||
if mod.esModule:
|
||||
esModules.add(mod.esModule)
|
||||
|
||||
if mod.js_name:
|
||||
if mod.js_name in js_services:
|
||||
raise Exception("Duplicate JS service name: %s" % mod.js_name)
|
||||
|
@ -805,6 +828,9 @@ def gen_substs(manifests):
|
|||
substs["component_jsms"] = (
|
||||
"\n".join(" %s," % strings.entry_to_cxx(jsm) for jsm in sorted(jsms)) + "\n"
|
||||
)
|
||||
substs["component_esmodules"] = (
|
||||
"\n".join(" %s," % strings.entry_to_cxx(esModule) for esModule in sorted(esModules)) + "\n"
|
||||
)
|
||||
|
||||
substs["interfaces"] = gen_interfaces(interfaces)
|
||||
|
||||
|
|
|
@ -1877,6 +1877,15 @@ nsComponentManagerImpl::GetComponentJSMs(nsIUTF8StringEnumerator** aJSMs) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComponentManagerImpl::GetComponentESModules(
|
||||
nsIUTF8StringEnumerator** aESModules) {
|
||||
nsCOMPtr<nsIUTF8StringEnumerator> result =
|
||||
StaticComponents::GetComponentESModules();
|
||||
result.forget(aESModules);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComponentManagerImpl::GetManifestLocations(nsIArray** aLocations) {
|
||||
NS_ENSURE_ARG_POINTER(aLocations);
|
||||
|
|
|
@ -101,6 +101,12 @@ interface nsIComponentManager : nsISupports
|
|||
* should only be used in automation.
|
||||
*/
|
||||
nsIUTF8StringEnumerator getComponentJSMs();
|
||||
|
||||
/**
|
||||
* Returns a list of ESM URLs which are used to create components. This
|
||||
* should only be used in automation.
|
||||
*/
|
||||
nsIUTF8StringEnumerator getComponentESModules();
|
||||
};
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче