Bug 1451513 Part 1: Allow registering chrome: content resources
MozReview-Commit-ID: IuUnzb24jCN
--- a/toolkit/mozapps/extensions/AddonManagerStartup.cpp
+++ b/toolkit/mozapps/extensions/AddonManagerStartup.cpp
@@ -665,35 +665,38 @@ static bool sObserverRegistered;
class RegistryEntries final : public nsIJSRAIIHelper
, public LinkedListElement<RegistryEntries>
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIJSRAIIHELPER
using Override = AutoTArray<nsCString, 2>;
+ using Content = AutoTArray<nsCString, 2>;
using Locale = AutoTArray<nsCString, 3>;
- RegistryEntries(FileLocation& location, nsTArray<Override>&& overrides, nsTArray<Locale>&& locales)
+ RegistryEntries(FileLocation& location, nsTArray<Override>&& overrides, nsTArray<Content>&& content, nsTArray<Locale>&& locales)
: mLocation(location)
, mOverrides(std::move(overrides))
+ , mContent(std::move(content))
, mLocales(std::move(locales))
{}
void Register();
protected:
virtual ~RegistryEntries()
{
Unused << Destruct();
}
private:
FileLocation mLocation;
const nsTArray<Override> mOverrides;
+ const nsTArray<Content> mContent;
const nsTArray<Locale> mLocales;
};
NS_IMPL_ISUPPORTS(RegistryEntries, nsIJSRAIIHelper)
void
RegistryEntries::Register()
{
@@ -701,16 +704,21 @@ RegistryEntries::Register()
nsChromeRegistry::ManifestProcessingContext context(NS_EXTENSION_LOCATION, mLocation);
for (auto& override : mOverrides) {
const char* args[] = {override[0].get(), override[1].get()};
cr->ManifestOverride(context, 0, const_cast<char**>(args), 0);
}
+ for (auto& content: mContent) {
+ const char* args[] = {content[0].get(), content[1].get()};
+ cr->ManifestContent(context, 0, const_cast<char**>(args), 0);
+ }
+
for (auto& locale : mLocales) {
const char* args[] = {locale[0].get(), locale[1].get(), locale[2].get()};
cr->ManifestLocale(context, 0, const_cast<char**>(args), 0);
}
}
NS_IMETHODIMP
RegistryEntries::Destruct()
@@ -746,16 +754,17 @@ AddonManagerStartup::RegisterChrome(nsIU
NS_ENSURE_ARG_POINTER(manifestURI);
NS_ENSURE_TRUE(IsArray(locations), NS_ERROR_INVALID_ARG);
FileLocation location;
MOZ_TRY_VAR(location, GetFileLocation(manifestURI));
nsTArray<RegistryEntries::Locale> locales;
+ nsTArray<RegistryEntries::Content> content;
nsTArray<RegistryEntries::Override> overrides;
JS::RootedObject locs(cx, &locations.toObject());
JS::RootedValue arrayVal(cx);
JS::RootedObject array(cx);
for (auto elem : ArrayIter(cx, locs)) {
arrayVal = elem.Value();
@@ -773,16 +782,19 @@ AddonManagerStartup::RegisterChrome(nsIU
NS_ENSURE_TRUE(vals.Length() > 0, NS_ERROR_INVALID_ARG);
nsCString type = vals[0];
vals.RemoveElementAt(0);
if (type.EqualsLiteral("override")) {
NS_ENSURE_TRUE(vals.Length() == 2, NS_ERROR_INVALID_ARG);
overrides.AppendElement(vals);
+ } else if (type.EqualsLiteral("content")) {
+ NS_ENSURE_TRUE(vals.Length() == 2, NS_ERROR_INVALID_ARG);
+ content.AppendElement(vals);
} else if (type.EqualsLiteral("locale")) {
NS_ENSURE_TRUE(vals.Length() == 3, NS_ERROR_INVALID_ARG);
locales.AppendElement(vals);
} else {
return NS_ERROR_INVALID_ARG;
}
}
@@ -791,16 +803,17 @@ AddonManagerStartup::RegisterChrome(nsIU
NS_ENSURE_TRUE(obs, NS_ERROR_UNEXPECTED);
obs->AddObserver(this, "chrome-manifests-loaded", false);
sObserverRegistered = true;
}
auto entry = MakeRefPtr<RegistryEntries>(location,
std::move(overrides),
+ std::move(content),
std::move(locales));
entry->Register();
GetRegistryEntries().insertBack(entry);
entry.forget(result);
return NS_OK;
}
--- a/toolkit/mozapps/extensions/test/xpcshell/test_registerchrome.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_registerchrome.js
@@ -11,59 +11,68 @@ add_task(async function() {
let file1 = getFileURI("file1");
let file2 = getFileURI("file2");
let uri1 = getFileURI("chrome.manifest");
let uri2 = getFileURI("manifest.json");
let overrideURL = Services.io.newURI("chrome://global/content/foo");
+ let contentURL = Services.io.newURI("chrome://test/content/foo");
let localeURL = Services.io.newURI("chrome://global/locale/foo");
let origOverrideURL = registry.convertChromeURL(overrideURL);
let origLocaleURL = registry.convertChromeURL(localeURL);
// eslint-disable-next-line no-unused-vars
let entry1 = aomStartup.registerChrome(uri1, [
["override", "chrome://global/content/foo", file1.spec],
+ ["content", "test", file2.spec + "/"],
["locale", "global", "en-US", file2.spec + "/"],
]);
let entry2 = aomStartup.registerChrome(uri2, [
["override", "chrome://global/content/foo", file2.spec],
+ ["content", "test", file1.spec + "/"],
["locale", "global", "en-US", file1.spec + "/"],
]);
// Initially, the second entry should override the first.
equal(registry.convertChromeURL(overrideURL).spec, file2.spec);
- equal(registry.convertChromeURL(localeURL).spec, file1.spec + "/foo");
+ let file = file1.spec + "/foo";
+ equal(registry.convertChromeURL(contentURL).spec, file);
+ equal(registry.convertChromeURL(localeURL).spec, file);
- // After destroying the second entry, the first entry should not take
+ // After destroying the second entry, the first entry should now take
// precedence.
entry2.destruct();
equal(registry.convertChromeURL(overrideURL).spec, file1.spec);
- equal(registry.convertChromeURL(localeURL).spec, file2.spec + "/foo");
+ file = file2.spec + "/foo";
+ equal(registry.convertChromeURL(contentURL).spec, file);
+ equal(registry.convertChromeURL(localeURL).spec, file);
// After dropping the reference to the first entry and allowing it to
// be GCed, we should be back to the original entries.
entry1 = null;
Cu.forceGC();
Cu.forceCC();
equal(registry.convertChromeURL(overrideURL).spec, origOverrideURL.spec);
equal(registry.convertChromeURL(localeURL).spec, origLocaleURL.spec);
+ Assert.throws(() => registry.convertChromeURL(contentURL),
+ e => e.result == Cr.NS_ERROR_FILE_NOT_FOUND,
+ "chrome://test/ should no longer be registered");
});
add_task(async function() {
const INVALID_VALUES = [
{},
"foo",
["foo"],
[{}],
[[]],
- [["content", "foo", "bar"]],
[["locale", "global"]],
[["locale", "global", "en", "foo", "foo"]],
[["override", "en"]],
[["override", "en", "US", "OR"]],
];
let uri = getFileURI("chrome.manifest");
for (let arg of INVALID_VALUES) {