Bug 1341458 - Move homepage to chrome_settings_overrides. r=mixedpuppy
MozReview-Commit-ID: 5wtaUxXco8z
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/ext-chrome-settings-overrides.js
@@ -0,0 +1,31 @@
+/* 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 (manifest.chrome_settings_overrides.homepage) {
+ ExtensionPreferencesManager.setSetting(extension, "homepage_override",
+ manifest.chrome_settings_overrides.homepage);
+ }
+});
+/* eslint-enable mozilla/balanced-listeners */
+
+ExtensionPreferencesManager.addSetting("homepage_override", {
+ prefNames: [
+ "browser.startup.homepage",
+ ],
+ setCallback(value) {
+ return {
+ "browser.startup.homepage": value,
+ };
+ },
+});
--- 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
@@ -27,16 +28,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,25 @@
+[
+ {
+ "namespace": "manifest",
+ "types": [
+ {
+ "$extend": "WebExtensionManifest",
+ "properties": {
+ "chrome_settings_overrides": {
+ "type": "object",
+ "optional": true,
+ "additionalProperties": { "$ref": "UnrecognizedProperty" },
+ "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/test/browser/browser-common.ini
+++ b/browser/components/extensions/test/browser/browser-common.ini
@@ -114,16 +114,17 @@ support-files =
[browser_ext_tabs_sendMessage.js]
[browser_ext_tabs_cookieStoreId.js]
[browser_ext_tabs_update.js]
[browser_ext_tabs_zoom.js]
[browser_ext_tabs_update_url.js]
[browser_ext_themes_icons.js]
[browser_ext_topwindowid.js]
[browser_ext_url_overrides_newtab.js]
+[browser_ext_url_overrides_home.js]
[browser_ext_webRequest.js]
[browser_ext_webNavigation_frameId0.js]
[browser_ext_webNavigation_getFrames.js]
[browser_ext_webNavigation_onCreatedNavigationTarget.js]
[browser_ext_webNavigation_onCreatedNavigationTarget_window_open.js]
[browser_ext_webNavigation_urlbar_transitions.js]
[browser_ext_windows.js]
[browser_ext_windows_create.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_url_overrides_home.js
@@ -0,0 +1,184 @@
+/* -*- 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");
+XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
+ "resource://gre/modules/AddonManager.jsm");
+
+// 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_home_page() {
+ let defaultHomePage = Preferences.get("browser.startup.homepage");
+
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {"chrome_settings_overrides": {}},
+ useAddonManager: "temporary",
+ });
+
+ let ext2 = ExtensionTestUtils.loadExtension({
+ manifest: {"chrome_settings_overrides": {homepage: HOME_URI_2}},
+ useAddonManager: "temporary",
+ });
+
+ let ext3 = ExtensionTestUtils.loadExtension({
+ manifest: {"chrome_settings_overrides": {homepage: HOME_URI_3}},
+ useAddonManager: "temporary",
+ });
+
+ let ext4 = ExtensionTestUtils.loadExtension({
+ manifest: {"chrome_settings_overrides": {homepage: HOME_URI_4}},
+ useAddonManager: "temporary",
+ });
+
+ yield ext1.startup();
+
+ is(Preferences.get("browser.startup.homepage"), defaultHomePage,
+ "Home url should be the default");
+
+ // 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();
+ yield prefPromise;
+
+ ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_2),
+ "Home url should be overridden by the second extension.");
+
+ // 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 overridden by the second extension.");
+
+ prefPromise = promisePrefChangeObserved("browser.startup.homepage");
+ yield ext3.startup();
+ yield prefPromise;
+
+ ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_3),
+ "Home url should be overridden 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.");
+
+ 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.");
+
+
+ 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 default");
+});
+
+const HOME_URI_1 = "http://example.com/";
+const USER_URI = "http://example.edu/";
+
+add_task(function* test_extension_setting_home_page_back() {
+ let defaultHomePage = Preferences.get("browser.startup.homepage");
+
+ Preferences.set("browser.startup.homepage", USER_URI);
+
+ is(Preferences.get("browser.startup.homepage"), USER_URI,
+ "Home url should be the user set value");
+
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {"chrome_settings_overrides": {homepage: HOME_URI_1}},
+ useAddonManager: "temporary",
+ });
+
+ // 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 ext1.startup();
+ yield prefPromise;
+
+ ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
+ "Home url should be overridden by the second extension.");
+
+ prefPromise = promisePrefChangeObserved("browser.startup.homepage");
+ yield ext1.unload();
+ yield prefPromise;
+
+ is(Preferences.get("browser.startup.homepage"), USER_URI,
+ "Home url should be the user set value");
+
+ Preferences.reset("browser.startup.homepage");
+
+ is(Preferences.get("browser.startup.homepage"), defaultHomePage,
+ "Home url should be the default");
+});
+
+add_task(function* test_disable() {
+ let defaultHomePage = Preferences.get("browser.startup.homepage");
+
+ const ID = "id@tests.mozilla.org";
+
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ applications: {
+ gecko: {
+ id: ID,
+ },
+ },
+ "chrome_settings_overrides": {
+ homepage: HOME_URI_1,
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ let prefPromise = promisePrefChangeObserved("browser.startup.homepage");
+ yield ext1.startup();
+ yield prefPromise;
+
+ ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
+ "Home url should be overridden by the extension.");
+
+ let addon = yield AddonManager.getAddonByID(ID);
+ is(addon.id, ID);
+
+ prefPromise = promisePrefChangeObserved("browser.startup.homepage");
+ addon.userDisabled = true;
+ yield prefPromise;
+
+ is(Preferences.get("browser.startup.homepage"), defaultHomePage,
+ "Home url should be the default");
+
+ prefPromise = promisePrefChangeObserved("browser.startup.homepage");
+ addon.userDisabled = false;
+ yield prefPromise;
+
+ ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
+ "Home url should be overridden by the extension.");
+
+ prefPromise = promisePrefChangeObserved("browser.startup.homepage");
+ yield ext1.unload();
+ yield prefPromise;
+
+ is(Preferences.get("browser.startup.homepage"), defaultHomePage,
+ "Home url should be the default");
+});
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -11,16 +11,17 @@
* openContextMenu closeContextMenu
* openExtensionContextMenu closeExtensionContextMenu
* openActionContextMenu openSubmenu closeActionContextMenu
* openTabContextMenu closeTabContextMenu
* imageBuffer imageBufferFromDataURI
* 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
@@ -343,8 +344,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();
+ }));
+}