Bug 1407999 - Support locked prefs for homepage r=jaws

MozReview-Commit-ID: Fxo0jh6KbOt

--HG--
extra : rebase_source : 8eb18e4ca98cfe6caba8304b2a0b30b41a0e6937
This commit is contained in:
Mark Striemer 2017-10-12 12:47:36 -05:00
Родитель 302cef9ace
Коммит 1a03f9f88c
2 изменённых файлов: 167 добавлений и 13 удалений

Просмотреть файл

@ -618,15 +618,24 @@ var gMainPane = {
// Set the "Use Current Page(s)" button's text and enabled state.
this._updateUseCurrentButton();
// This is an async task.
handleControllingExtension("prefs", "homepage_override")
.then((isControlled) => {
// Disable or enable the inputs based on if this is controlled by an extension.
document.querySelectorAll("#browserHomePage, .homepage-button")
.forEach((button) => {
button.disabled = isControlled;
});
});
function setInputDisabledStates(isControlled) {
// Disable or enable the inputs based on if this is controlled by an extension.
document.querySelectorAll("#browserHomePage, .homepage-button")
.forEach((element) => {
let isLocked = document.getElementById(element.getAttribute("preference")).locked;
element.disabled = isLocked || isControlled;
});
}
if (homePref.locked) {
// An extension can't control these settings if they're locked.
hideControllingExtension("homepage_override");
setInputDisabledStates(false);
} else {
// Asynchronously update the extension controlled UI.
handleControllingExtension("prefs", "homepage_override")
.then(setInputDisabledStates);
}
// If the pref is set to about:home or about:newtab, set the value to ""
// to show the placeholder text (about:home title) rather than

Просмотреть файл

@ -32,19 +32,24 @@ function installAddon(xpiName) {
});
}
function waitForMessageChange(messageId, cb) {
function waitForMutation(target, opts, cb) {
return new Promise((resolve) => {
let target = gBrowser.contentDocument.getElementById(messageId);
let observer = new MutationObserver(() => {
if (cb(target)) {
if (!cb || cb(target)) {
observer.disconnect();
resolve();
}
});
observer.observe(target, { attributes: true, attributeFilter: ["hidden"] });
observer.observe(target, opts);
});
}
function waitForMessageChange(messageId, cb) {
return waitForMutation(
gBrowser.contentDocument.getElementById(messageId),
{ attributes: true, attributeFilter: ["hidden"] }, cb);
}
function waitForMessageHidden(messageId) {
return waitForMessageChange(messageId, target => target.hidden);
}
@ -90,6 +95,146 @@ add_task(async function testExtensionControlledHomepage() {
is(doc.getElementById("browserHomePage").disabled, false, "The homepage input is enabled");
is(controlledContent.hidden, true, "The extension controlled row is hidden");
let addon = await AddonManager.getAddonByID("@set_homepage");
// Enable the extension so we get the UNINSTALL event, which is needed by
// ExtensionPreferencesManager to clean up properly.
// FIXME: See https://bugzilla.mozilla.org/show_bug.cgi?id=1408226.
addon.userDisabled = false;
await waitForMessageShown("browserHomePageExtensionContent");
// Do the uninstall now that the enable code has been run.
addon.uninstall();
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function testPrefLockedHomepage() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
let doc = gBrowser.contentDocument;
is(gBrowser.currentURI.spec, "about:preferences#general",
"#general should be in the URI for about:preferences");
let homePagePref = "browser.startup.homepage";
let buttonPrefs = [
"pref.browser.homepage.disable_button.current_page",
"pref.browser.homepage.disable_button.bookmark_page",
"pref.browser.homepage.disable_button.restore_default",
];
let homePageInput = doc.getElementById("browserHomePage");
let prefs = Services.prefs.getDefaultBranch(null);
let mutationOpts = {attributes: true, attributeFilter: ["disabled"]};
let controlledContent = doc.getElementById("browserHomePageExtensionContent");
// Helper functions.
let getButton = pref => doc.querySelector(`.homepage-button[preference="${pref}"`);
let waitForAllMutations = () => Promise.all(
buttonPrefs.map(pref => waitForMutation(getButton(pref), mutationOpts))
.concat([waitForMutation(homePageInput, mutationOpts)]));
let getHomepage = () => Services.prefs.getCharPref("browser.startup.homepage");
let originalHomepage = getHomepage();
let extensionHomepage = "https://developer.mozilla.org/";
let lockedHomepage = "http://www.yahoo.com";
let lockPrefs = () => {
buttonPrefs.forEach(pref => {
prefs.setBoolPref(pref, true);
prefs.lockPref(pref);
});
// Do the homepage last since that's the only pref that triggers a UI update.
prefs.setCharPref(homePagePref, lockedHomepage);
prefs.lockPref(homePagePref);
};
let unlockPrefs = () => {
buttonPrefs.forEach(pref => {
prefs.unlockPref(pref);
prefs.setBoolPref(pref, false);
});
// Do the homepage last since that's the only pref that triggers a UI update.
prefs.unlockPref(homePagePref);
prefs.setCharPref(homePagePref, originalHomepage);
};
ok(originalHomepage != extensionHomepage, "The extension will change the homepage");
// Install an extension that sets the homepage to MDN.
await installAddon("set_homepage.xpi");
await waitForMessageShown(controlledContent.id);
// Check that everything is still disabled, homepage didn't change.
is(getHomepage(), extensionHomepage, "The reported homepage is set by the extension");
is(homePageInput.value, extensionHomepage, "The homepage is set by the extension");
is(homePageInput.disabled, true, "Homepage is disabled when set by extension");
buttonPrefs.forEach(pref => {
is(getButton(pref).disabled, true, `${pref} is disabled when set by extension`);
});
is(controlledContent.hidden, false, "The extension controlled message is shown");
// Lock all of the prefs, wait for the UI to update.
let messageHidden = waitForMessageHidden(controlledContent.id);
lockPrefs();
await messageHidden;
// Check that everything is now disabled.
is(getHomepage(), lockedHomepage, "The reported homepage is set by the pref");
is(homePageInput.value, lockedHomepage, "The homepage is set by the pref");
is(homePageInput.disabled, true, "The homepage is disabed when the pref is locked");
buttonPrefs.forEach(pref => {
is(getButton(pref).disabled, true, `The ${pref} button is disabled when locked`);
});
is(controlledContent.hidden, true, "The extension controlled message is hidden when locked");
// Unlock the prefs, wait for the UI to update.
let messageShown = waitForMessageShown(controlledContent.id);
unlockPrefs();
await messageShown;
// Verify that the UI is showing the extension's settings.
is(homePageInput.value, extensionHomepage, "The homepage is set by the extension");
is(homePageInput.disabled, true, "Homepage is disabled when set by extension");
buttonPrefs.forEach(pref => {
is(getButton(pref).disabled, true, `${pref} is disabled when set by extension`);
});
is(controlledContent.hidden, false, "The extension controlled message is shown when unlocked");
// Uninstall the add-on.
let addon = await AddonManager.getAddonByID("@set_homepage");
addon.uninstall();
await waitForMessageHidden(controlledContent.id);
// Check that everything is now enabled again.
is(getHomepage(), originalHomepage, "The reported homepage is reset to original value");
is(homePageInput.value, "", "The homepage is empty");
is(homePageInput.disabled, false, "The homepage is enabled after clearing lock");
buttonPrefs.forEach(pref => {
is(getButton(pref).disabled, false, `The ${pref} button is enabled when unlocked`);
});
// Lock the prefs without an extension.
lockPrefs();
await waitForAllMutations();
// Check that everything is now disabled.
is(getHomepage(), lockedHomepage, "The reported homepage is set by the pref");
is(homePageInput.value, lockedHomepage, "The homepage is set by the pref");
is(homePageInput.disabled, true, "The homepage is disabed when the pref is locked");
buttonPrefs.forEach(pref => {
is(getButton(pref).disabled, true, `The ${pref} button is disabled when locked`);
});
// Unlock the prefs without an extension.
unlockPrefs();
await waitForAllMutations();
// Check that everything is enabled again.
is(getHomepage(), originalHomepage, "The homepage is reset to the original value");
is(homePageInput.value, "", "The homepage is clear after being unlocked");
is(homePageInput.disabled, false, "The homepage is enabled after clearing lock");
buttonPrefs.forEach(pref => {
is(getButton(pref).disabled, false, `The ${pref} button is enabled when unlocked`);
});
is(controlledContent.hidden, true,
"The extension controlled message is hidden when unlocked with no extension");
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});