Bug 1341458 - Move homepage to chrome_settings_overrides. r?aswan, kmag
MozReview-Commit-ID: 2P7H39uAQef
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/ext-chrome-settings-overrides.js
@@ -0,0 +1,35 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ExtensionPreferencesManager",
+ "resource://gre/modules/ExtensionPreferencesManager.jsm");
+
+/* eslint-disable mozilla/balanced-listeners */
+extensions.on("manifest_chrome_settings_overrides", (type, directive, extension, manifest) => {
+ if ("homepage" in manifest.chrome_settings_overrides &&
+ manifest.chrome_settings_overrides.homepage) {
+ ExtensionPreferencesManager.addSetting("homepage_override", {
+ prefNames: [
+ "browser.startup.homepage",
+ ],
+ setCallback(value) {
+ return {
+ "browser.startup.homepage": value,
+ };
+ },
+ });
+ ExtensionPreferencesManager.setSetting(extension, "homepage_override",
+ manifest.chrome_settings_overrides.homepage);
+ }
+});
+
+extensions.on("shutdown", (type, extension) => {
+ ExtensionPreferencesManager.unsetSetting(extension, "homepage_override");
+});
+/* eslint-enable mozilla/balanced-listeners */
--- a/browser/components/extensions/ext-url-overrides.js
+++ b/browser/components/extensions/ext-url-overrides.js
@@ -3,102 +3,47 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
"@mozilla.org/browser/aboutnewtab-service;1",
"nsIAboutNewTabService");
-XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
- "resource://gre/modules/Preferences.jsm");
// Bug 1320736 tracks creating a generic precedence manager for handling
// multiple addons modifying the same properties, and bug 1330494 has been filed
// to track utilizing this manager for chrome_url_overrides. Until those land,
// the edge cases surrounding multiple addons using chrome_url_overrides will
// be ignored and precedence will be first come, first serve.
let overrides = {
// A queue of extensions in line to override the newtab page (sorted oldest to newest).
newtab: [],
- // A queue of extensions in line to override the home page (sorted oldest to newest).
- home: [],
};
-/**
- * Resets the specified page to its default value.
- *
- * @param {string} page The page to override. Accepted values are "newtab" and "home".
- */
-function resetPage(page) {
- switch (page) {
- case "newtab":
- aboutNewTabService.resetNewTabURL();
- break;
- case "home":
- Preferences.reset("browser.startup.homepage");
- break;
- default:
- throw new Error("Unrecognized override type");
- }
-}
-
-/**
- * Overrides the specified page to the specified URL.
- *
- * @param {string} page The page to override. Accepted values are "newtab" and "home".
- * @param {string} url The resolved URL to use for the page override.
- */
-function overridePage(page, url) {
- switch (page) {
- case "newtab":
- aboutNewTabService.newTabURL = url;
- break;
- case "home":
- Preferences.set("browser.startup.homepage", url);
- break;
- default:
- throw new Error("Unrecognized override type");
- }
-}
-
-/**
- * Updates the page to the URL specified by the extension next in line. If no extensions
- * are in line, the page is reset to its default value.
- *
- * @param {string} page The page to override.
- */
-function updatePage(page) {
- if (overrides[page].length) {
- overridePage(page, overrides[page][0].url);
- } else {
- resetPage(page);
- }
-}
-
/* eslint-disable mozilla/balanced-listeners */
extensions.on("manifest_chrome_url_overrides", (type, directive, extension, manifest) => {
- if (Object.keys(overrides).length > 1) {
- extension.manifestError("Extensions can override only one page.");
- }
+ if (manifest.chrome_url_overrides.newtab) {
+ let newtab = manifest.chrome_url_overrides.newtab;
+ let url = extension.baseURI.resolve(newtab);
- for (let page of Object.keys(overrides)) {
- if (manifest.chrome_url_overrides[page]) {
- let relativeURL = manifest.chrome_url_overrides[page];
- let url = extension.baseURI.resolve(relativeURL);
- // Store the extension ID instead of a hard reference to the extension.
- overrides[page].push({id: extension.id, url});
- updatePage(page);
- break;
+ // Only set the newtab URL if no other extension is overriding it.
+ if (!overrides.newtab.length) {
+ aboutNewTabService.newTabURL = url;
}
+
+ overrides.newtab.push({id: extension.id, url});
}
});
extensions.on("shutdown", (type, extension) => {
- for (let page of Object.keys(overrides)) {
- let i = overrides[page].findIndex(o => o.id === extension.id);
- if (i !== -1) {
- overrides[page].splice(i, 1);
- updatePage(page);
+ let i = overrides.newtab.findIndex(o => o.id === extension.id);
+ if (i !== -1) {
+ overrides.newtab.splice(i, 1);
+
+ if (overrides.newtab.length) {
+ aboutNewTabService.newTabURL = overrides.newtab[0].url;
+ } else {
+ aboutNewTabService.resetNewTabURL();
}
}
});
/* eslint-enable mozilla/balanced-listeners */
--- a/browser/components/extensions/extensions-browser.manifest
+++ b/browser/components/extensions/extensions-browser.manifest
@@ -1,12 +1,13 @@
# scripts
category webextension-scripts bookmarks chrome://browser/content/ext-bookmarks.js
category webextension-scripts browserAction chrome://browser/content/ext-browserAction.js
category webextension-scripts browsingData chrome://browser/content/ext-browsingData.js
+category webextension-scripts chrome-settings-overrides chrome://browser/content/ext-chrome-settings-overrides.js
category webextension-scripts commands chrome://browser/content/ext-commands.js
category webextension-scripts contextMenus chrome://browser/content/ext-contextMenus.js
category webextension-scripts desktop-runtime chrome://browser/content/ext-desktop-runtime.js
category webextension-scripts devtools chrome://browser/content/ext-devtools.js
category webextension-scripts devtools-inspectedWindow chrome://browser/content/ext-devtools-inspectedWindow.js
category webextension-scripts devtools-network chrome://browser/content/ext-devtools-network.js
category webextension-scripts devtools-panels chrome://browser/content/ext-devtools-panels.js
category webextension-scripts history chrome://browser/content/ext-history.js
@@ -28,16 +29,17 @@ category webextension-scripts-devtools d
category webextension-scripts-addon contextMenus chrome://browser/content/ext-c-contextMenus.js
category webextension-scripts-addon omnibox chrome://browser/content/ext-c-omnibox.js
category webextension-scripts-addon tabs chrome://browser/content/ext-c-tabs.js
# schemas
category webextension-schemas bookmarks chrome://browser/content/schemas/bookmarks.json
category webextension-schemas browser_action chrome://browser/content/schemas/browser_action.json
category webextension-schemas browsing_data chrome://browser/content/schemas/browsing_data.json
+category webextension-schemas chrome_settings_overrides chrome://browser/content/schemas/chrome_settings_overrides.json
category webextension-schemas commands chrome://browser/content/schemas/commands.json
category webextension-schemas context_menus chrome://browser/content/schemas/context_menus.json
category webextension-schemas context_menus_internal chrome://browser/content/schemas/context_menus_internal.json
category webextension-schemas devtools chrome://browser/content/schemas/devtools.json
category webextension-schemas devtools_inspected_window chrome://browser/content/schemas/devtools_inspected_window.json
category webextension-schemas devtools_network chrome://browser/content/schemas/devtools_network.json
category webextension-schemas devtools_panels chrome://browser/content/schemas/devtools_panels.json
category webextension-schemas history chrome://browser/content/schemas/history.json
--- a/browser/components/extensions/jar.mn
+++ b/browser/components/extensions/jar.mn
@@ -10,16 +10,17 @@ browser.jar:
#endif
#ifdef XP_WIN
content/browser/extension-win-panel.css
#endif
content/browser/extension.svg
content/browser/ext-bookmarks.js
content/browser/ext-browserAction.js
content/browser/ext-browsingData.js
+ content/browser/ext-chrome-settings-overrides.js
content/browser/ext-commands.js
content/browser/ext-contextMenus.js
content/browser/ext-desktop-runtime.js
content/browser/ext-devtools.js
content/browser/ext-devtools-inspectedWindow.js
content/browser/ext-devtools-network.js
content/browser/ext-devtools-panels.js
content/browser/ext-history.js
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/schemas/chrome_settings_overrides.json
@@ -0,0 +1,24 @@
+[
+ {
+ "namespace": "manifest",
+ "types": [
+ {
+ "$extend": "WebExtensionManifest",
+ "properties": {
+ "chrome_settings_overrides": {
+ "type": "object",
+ "optional": true,
+ "properties": {
+ "homepage": {
+ "type": "string",
+ "format": "url",
+ "optional": true,
+ "preprocess": "localize"
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+]
\ No newline at end of file
--- a/browser/components/extensions/schemas/jar.mn
+++ b/browser/components/extensions/schemas/jar.mn
@@ -1,16 +1,17 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
browser.jar:
content/browser/schemas/bookmarks.json
content/browser/schemas/browser_action.json
content/browser/schemas/browsing_data.json
+ content/browser/schemas/chrome_settings_overrides.json
content/browser/schemas/commands.json
content/browser/schemas/context_menus.json
content/browser/schemas/context_menus_internal.json
content/browser/schemas/devtools.json
content/browser/schemas/devtools_inspected_window.json
content/browser/schemas/devtools_network.json
content/browser/schemas/devtools_panels.json
content/browser/schemas/history.json
--- a/browser/components/extensions/schemas/url_overrides.json
+++ b/browser/components/extensions/schemas/url_overrides.json
@@ -9,21 +9,16 @@
"type": "object",
"optional": true,
"properties": {
"newtab": {
"$ref": "ExtensionURL",
"optional": true,
"preprocess": "localize"
},
- "home": {
- "$ref": "ExtensionURL",
- "optional": true,
- "preprocess": "localize"
- },
"bookmarks": {
"unsupported": true,
"$ref": "ExtensionURL",
"optional": true,
"preprocess": "localize"
},
"history": {
"unsupported": true,
--- a/browser/components/extensions/test/browser/browser-common.ini
+++ b/browser/components/extensions/test/browser/browser-common.ini
@@ -112,17 +112,16 @@ support-files =
[browser_ext_tabs_cookieStoreId.js]
[browser_ext_tabs_update.js]
[browser_ext_tabs_zoom.js]
[browser_ext_tabs_update_url.js]
[browser_ext_themes_chromeparity.js]
[browser_ext_themes_dynamic_updates.js]
[browser_ext_themes_lwtsupport.js]
[browser_ext_topwindowid.js]
-[browser_ext_url_overrides_all.js]
[browser_ext_url_overrides_home.js]
[browser_ext_url_overrides_newtab.js]
[browser_ext_webRequest.js]
[browser_ext_webNavigation_frameId0.js]
[browser_ext_webNavigation_getFrames.js]
[browser_ext_webNavigation_urlbar_transitions.js]
[browser_ext_windows.js]
[browser_ext_windows_create.js]
deleted file mode 100644
--- a/browser/components/extensions/test/browser/browser_ext_url_overrides_all.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-
-"use strict";
-
-XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
- "@mozilla.org/browser/aboutnewtab-service;1",
- "nsIAboutNewTabService");
-
-const NEWTAB_URI = "webext-newtab.html";
-const HOME_URI = "webext-home.html";
-
-add_task(function* test_extensions_overriding_different_pages() {
- let defaultHomePage = Preferences.get("browser.startup.homepage");
- let defaultNewtabPage = aboutNewTabService.newTabURL;
-
- is(Preferences.get("browser.startup.homepage"), defaultHomePage,
- `Default home url should be ${defaultHomePage}`);
- is(aboutNewTabService.newTabURL, defaultNewtabPage,
- `Default newtab url should be ${defaultNewtabPage}`);
-
- let ext1 = ExtensionTestUtils.loadExtension({
- manifest: {"chrome_url_overrides": {}},
- });
-
- let ext2 = ExtensionTestUtils.loadExtension({
- manifest: {"chrome_url_overrides": {newtab: NEWTAB_URI}},
- });
-
- let ext3 = ExtensionTestUtils.loadExtension({
- manifest: {"chrome_url_overrides": {home: HOME_URI}},
- });
-
- yield ext1.startup();
-
- is(aboutNewTabService.newTabURL, defaultNewtabPage,
- `Default newtab url should still be ${defaultNewtabPage}`);
- is(Preferences.get("browser.startup.homepage"), defaultHomePage,
- `Default home url should be ${defaultHomePage}`);
-
- yield ext2.startup();
-
- ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI),
- "Newtab url should be overriden by the second extension.");
- is(Preferences.get("browser.startup.homepage"), defaultHomePage,
- `Default home url should be ${defaultHomePage}`);
-
- yield ext1.unload();
-
- ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI),
- "Newtab url should still be overriden by the second extension.");
- is(Preferences.get("browser.startup.homepage"), defaultHomePage,
- `Default home url should be ${defaultHomePage}`);
-
- yield ext3.startup();
-
- ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI),
- "Newtab url should still be overriden by the second extension.");
- ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI),
- "Home url should be overriden by the third extension.");
-
- yield ext2.unload();
-
- is(aboutNewTabService.newTabURL, defaultNewtabPage,
- `Newtab url should be reset to ${defaultNewtabPage}`);
- ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI),
- "Home url should still be overriden by the third extension.");
-
- yield ext3.unload();
-
- is(aboutNewTabService.newTabURL, defaultNewtabPage,
- `Newtab url should be reset to ${defaultNewtabPage}`);
- is(Preferences.get("browser.startup.homepage"), defaultHomePage,
- `Home url should be reset to ${defaultHomePage}`);
-});
-
-add_task(function* test_extensions_with_multiple_overrides() {
- let ext = ExtensionTestUtils.loadExtension({
- manifest: {"chrome_url_overrides": {
- newtab: NEWTAB_URI,
- home: HOME_URI,
- }},
- });
-
- SimpleTest.waitForExplicitFinish();
- let waitForConsole = new Promise(resolve => {
- SimpleTest.monitorConsole(resolve, [{
- message: /Extensions can override only one page./,
- }]);
- });
-
- yield ext.startup();
- yield ext.unload();
-
- SimpleTest.endMonitorConsole();
- yield waitForConsole;
-});
--- a/browser/components/extensions/test/browser/browser_ext_url_overrides_home.js
+++ b/browser/components/extensions/test/browser/browser_ext_url_overrides_home.js
@@ -1,74 +1,95 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
-const HOME_URI_1 = "webext-home-1.html";
-const HOME_URI_2 = "webext-home-2.html";
-const HOME_URI_3 = "webext-home-3.html";
+// Named this way so they correspond to the extensions
+const HOME_URI_2 = "http://example.com/";
+const HOME_URI_3 = "http://example.org/";
+const HOME_URI_4 = "http://example.net/";
add_task(function* test_multiple_extensions_overriding_newtab_page() {
let defaultHomePage = Preferences.get("browser.startup.homepage");
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
`Default home url should be ${defaultHomePage}`);
let ext1 = ExtensionTestUtils.loadExtension({
- manifest: {"chrome_url_overrides": {}},
+ manifest: {"chrome_settings_overrides": {}},
+ useAddonManager: "temporary",
});
let ext2 = ExtensionTestUtils.loadExtension({
- manifest: {"chrome_url_overrides": {home: HOME_URI_1}},
+ manifest: {"chrome_settings_overrides": {homepage: HOME_URI_2}},
+ useAddonManager: "temporary",
});
let ext3 = ExtensionTestUtils.loadExtension({
- manifest: {"chrome_url_overrides": {home: HOME_URI_2}},
+ manifest: {"chrome_settings_overrides": {homepage: HOME_URI_3}},
+ useAddonManager: "temporary",
});
let ext4 = ExtensionTestUtils.loadExtension({
- manifest: {"chrome_url_overrides": {home: HOME_URI_3}},
+ manifest: {"chrome_settings_overrides": {homepage: HOME_URI_4}},
+ useAddonManager: "temporary",
});
yield ext1.startup();
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
`Default home url should still be ${defaultHomePage}`);
+ // Because we are expecting the pref to change when we start or unload, we
+ // need to wait on a pref change. This is because the pref management is
+ // async and can happen after the startup/unload is finished.
+ let prefPromise = promisePrefChangeObserved("browser.startup.homepage");
yield ext2.startup();
-
- ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
- "Home url should be overriden by the second extension.");
-
- yield ext1.unload();
+ yield prefPromise;
- ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
- "Home url should still be overriden by the second extension.");
-
- yield ext3.startup();
+ ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_2),
+ "Home url should be overridden by the second extension.");
- ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
- "Home url should still be overriden by the second extension.");
-
- yield ext2.unload();
+ // Because we are unloading an earlier extension, browser.startup.homepage won't change
+ yield ext1.unload();
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_2),
- "Home url should be overriden by the third extension.");
+ "Home url should be overridden by the second extension.");
+
+ prefPromise = promisePrefChangeObserved("browser.startup.homepage");
+ yield ext3.startup();
+ yield prefPromise;
- yield ext4.startup();
+ ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_3),
+ "Home url should be overridden by the third extension.");
- ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_2),
- "Home url should be overriden by the third extension.");
+ // Because we are unloading an earlier extension, browser.startup.homepage won't change
+ yield ext2.unload();
+
+ ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_3),
+ "Home url should be overridden by the third extension.");
- yield ext4.unload();
+ prefPromise = promisePrefChangeObserved("browser.startup.homepage");
+ yield ext4.startup();
+ yield prefPromise;
+
+ ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_4),
+ "Home url should be overridden by the third extension.");
+
- ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_2),
- "Home url should be overriden by the third extension.");
+ prefPromise = promisePrefChangeObserved("browser.startup.homepage");
+ yield ext4.unload();
+ yield prefPromise;
+ ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_3),
+ "Home url should be overridden by the third extension.");
+
+ prefPromise = promisePrefChangeObserved("browser.startup.homepage");
yield ext3.unload();
+ yield prefPromise;
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
- `Home url should be reset to ${defaultHomePage}`);
+ "Home url should be reset to default");
});
--- a/browser/components/extensions/test/browser/browser_ext_url_overrides_newtab.js
+++ b/browser/components/extensions/test/browser/browser_ext_url_overrides_newtab.js
@@ -71,21 +71,21 @@ add_task(function* test_multiple_extensi
is(aboutNewTabService.newTabURL, "about:newtab",
"Newtab url should be reset to about:newtab");
});
add_task(function* test_sending_message_from_newtab_page() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"chrome_url_overrides": {
- newtab: NEWTAB_URI_1,
+ newtab: NEWTAB_URI_2,
},
},
files: {
- [NEWTAB_URI_1]: `
+ [NEWTAB_URI_2]: `
<!DOCTYPE html>
<head>
<meta charset="utf-8"/></head>
<html>
<body>
<script src="newtab.js"></script>
</body>
</html>
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -10,16 +10,17 @@
* promisePopupShown promisePopupHidden
* openContextMenu closeContextMenu
* openExtensionContextMenu closeExtensionContextMenu
* openActionContextMenu openSubmenu closeActionContextMenu
* openTabContextMenu closeTabContextMenu
* imageBuffer getListStyleImage getPanelForNode
* awaitExtensionPanel awaitPopupResize
* promiseContentDimensions alterContent
+ * promisePrefChangeObserved
*/
const {AppConstants} = Cu.import("resource://gre/modules/AppConstants.jsm", {});
const {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm", {});
// We run tests under two different configurations, from browser.ini and
// browser-remote.ini. When running from browser-remote.ini, the tests are
// copied to the sub-directory "test-oop-extensions", which we detect here, and
@@ -337,8 +338,16 @@ function closePageAction(extension, win
if (node) {
return promisePopupShown(node).then(() => {
node.hidePopup();
});
}
return Promise.resolve();
}
+
+function promisePrefChangeObserved(pref) {
+ return new Promise((resolve, reject) =>
+ Preferences.observe(pref, function prefObserver() {
+ Preferences.ignore(pref, prefObserver);
+ resolve();
+ }));
+}