forked from mirrors/gecko-dev
333 lines
11 KiB
JavaScript
333 lines
11 KiB
JavaScript
/* 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 EXPORTED_SYMBOLS = ["SpecialMessageActions"];
|
|
|
|
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
const { XPCOMUtils } = ChromeUtils.import(
|
|
"resource://gre/modules/XPCOMUtils.jsm"
|
|
);
|
|
const DOH_DOORHANGER_DECISION_PREF = "doh-rollout.doorhanger-decision";
|
|
const NETWORK_TRR_MODE_PREF = "network.trr.mode";
|
|
|
|
XPCOMUtils.defineLazyModuleGetters(this, {
|
|
AddonManager: "resource://gre/modules/AddonManager.jsm",
|
|
UITour: "resource:///modules/UITour.jsm",
|
|
FxAccounts: "resource://gre/modules/FxAccounts.jsm",
|
|
MigrationUtils: "resource:///modules/MigrationUtils.jsm",
|
|
});
|
|
|
|
const SpecialMessageActions = {
|
|
// This is overridden by ASRouter.init
|
|
blockMessageById() {
|
|
throw new Error("ASRouter not intialized yet");
|
|
},
|
|
|
|
/**
|
|
* loadAddonIconInURLBar - load addons-notification icon by displaying
|
|
* box containing addons icon in urlbar. See Bug 1513882
|
|
*
|
|
* @param {Browser} browser browser element for showing addons icon
|
|
*/
|
|
loadAddonIconInURLBar(browser) {
|
|
if (!browser) {
|
|
return;
|
|
}
|
|
const chromeDoc = browser.ownerDocument;
|
|
let notificationPopupBox = chromeDoc.getElementById(
|
|
"notification-popup-box"
|
|
);
|
|
if (!notificationPopupBox) {
|
|
return;
|
|
}
|
|
if (
|
|
notificationPopupBox.style.display === "none" ||
|
|
notificationPopupBox.style.display === ""
|
|
) {
|
|
notificationPopupBox.style.display = "block";
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param {Browser} browser The revelant Browser
|
|
* @param {string} url URL to look up install location
|
|
* @param {string} telemetrySource Telemetry information to pass to getInstallForURL
|
|
*/
|
|
async installAddonFromURL(browser, url, telemetrySource = "amo") {
|
|
try {
|
|
this.loadAddonIconInURLBar(browser);
|
|
const aUri = Services.io.newURI(url);
|
|
const systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
|
|
|
|
// AddonManager installation source associated to the addons installed from activitystream's CFR
|
|
// and RTAMO (source is going to be "amo" if not configured explicitly in the message provider).
|
|
const telemetryInfo = { source: telemetrySource };
|
|
const install = await AddonManager.getInstallForURL(aUri.spec, {
|
|
telemetryInfo,
|
|
});
|
|
await AddonManager.installAddonFromWebpage(
|
|
"application/x-xpinstall",
|
|
browser,
|
|
systemPrincipal,
|
|
install
|
|
);
|
|
} catch (e) {
|
|
Cu.reportError(e);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Pin Firefox to taskbar.
|
|
*
|
|
* @param {Window} window Reference to a window object
|
|
*/
|
|
pinFirefoxToTaskbar(window) {
|
|
window.getShellService().pinToTaskbar();
|
|
},
|
|
|
|
/**
|
|
* Set browser as the operating system default browser.
|
|
*
|
|
* @param {Window} window Reference to a window object
|
|
*/
|
|
setDefaultBrowser(window) {
|
|
window.getShellService().setAsDefault();
|
|
},
|
|
|
|
/**
|
|
* Reset browser homepage and newtab to default with a certain section configuration
|
|
*
|
|
* @param {"default"|null} home Value to set for browser homepage
|
|
* @param {"default"|null} newtab Value to set for browser newtab
|
|
* @param {obj} layout Configuration options for newtab sections
|
|
* @returns {undefined}
|
|
*/
|
|
configureHomepage({ homePage = null, newtab = null, layout = null }) {
|
|
// Homepage can be default, blank or a custom url
|
|
if (homePage === "default") {
|
|
Services.prefs.clearUserPref("browser.startup.homepage");
|
|
}
|
|
// Newtab page can only be default or blank
|
|
if (newtab === "default") {
|
|
Services.prefs.clearUserPref("browser.newtabpage.enabled");
|
|
}
|
|
if (layout) {
|
|
// Existing prefs that interact with the newtab page layout, we default to true
|
|
// or payload configuration
|
|
let newtabConfigurations = [
|
|
[
|
|
// controls the search bar
|
|
"browser.newtabpage.activity-stream.showSearch",
|
|
layout.search,
|
|
],
|
|
[
|
|
// controls the topsites
|
|
"browser.newtabpage.activity-stream.feeds.topsites",
|
|
layout.topsites,
|
|
// User can control number of topsite rows
|
|
["browser.newtabpage.activity-stream.topSitesRows"],
|
|
],
|
|
[
|
|
// controls the highlights section
|
|
"browser.newtabpage.activity-stream.feeds.section.highlights",
|
|
layout.highlights,
|
|
// User can control number of rows and highlight sources
|
|
[
|
|
"browser.newtabpage.activity-stream.section.highlights.rows",
|
|
"browser.newtabpage.activity-stream.section.highlights.includeVisited",
|
|
"browser.newtabpage.activity-stream.section.highlights.includePocket",
|
|
"browser.newtabpage.activity-stream.section.highlights.includeDownloads",
|
|
"browser.newtabpage.activity-stream.section.highlights.includeBookmarks",
|
|
],
|
|
],
|
|
[
|
|
// controls the snippets section
|
|
"browser.newtabpage.activity-stream.feeds.snippets",
|
|
layout.snippets,
|
|
],
|
|
[
|
|
// controls the topstories section
|
|
"browser.newtabpage.activity-stream.feeds.system.topstories",
|
|
layout.topstories,
|
|
],
|
|
].filter(
|
|
// If a section has configs that the user changed we will skip that section
|
|
([, , sectionConfigs]) =>
|
|
!sectionConfigs ||
|
|
sectionConfigs.every(
|
|
prefName => !Services.prefs.prefHasUserValue(prefName)
|
|
)
|
|
);
|
|
|
|
for (let [prefName, prefValue] of newtabConfigurations) {
|
|
Services.prefs.setBoolPref(prefName, prefValue);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Processes "Special Message Actions", which are definitions of behaviors such as opening tabs
|
|
* installing add-ons, or focusing the awesome bar that are allowed to can be triggered from
|
|
* Messaging System interactions.
|
|
*
|
|
* @param {{type: string, data?: any}} action User action defined in message JSON.
|
|
* @param browser {Browser} The browser most relvant to the message.
|
|
*/
|
|
async handleAction(action, browser) {
|
|
const window = browser.ownerGlobal;
|
|
switch (action.type) {
|
|
case "SHOW_MIGRATION_WIZARD":
|
|
MigrationUtils.showMigrationWizard(window, [
|
|
MigrationUtils.MIGRATION_ENTRYPOINT_NEWTAB,
|
|
action.data?.source,
|
|
]);
|
|
break;
|
|
case "OPEN_PRIVATE_BROWSER_WINDOW":
|
|
// Forcefully open about:privatebrowsing
|
|
window.OpenBrowserWindow({ private: true });
|
|
break;
|
|
case "OPEN_URL":
|
|
window.openLinkIn(
|
|
Services.urlFormatter.formatURL(action.data.args),
|
|
action.data.where || "current",
|
|
{
|
|
private: false,
|
|
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal(
|
|
{}
|
|
),
|
|
csp: null,
|
|
}
|
|
);
|
|
break;
|
|
case "OPEN_ABOUT_PAGE":
|
|
let aboutPageURL = new URL(`about:${action.data.args}`);
|
|
if (action.data.entrypoint) {
|
|
aboutPageURL.search = action.data.entrypoint;
|
|
}
|
|
window.openTrustedLinkIn(
|
|
aboutPageURL.toString(),
|
|
action.data.where || "tab"
|
|
);
|
|
break;
|
|
case "OPEN_PREFERENCES_PAGE":
|
|
window.openPreferences(
|
|
action.data.category || action.data.args,
|
|
action.data.entrypoint && {
|
|
urlParams: { entrypoint: action.data.entrypoint },
|
|
}
|
|
);
|
|
break;
|
|
case "OPEN_APPLICATIONS_MENU":
|
|
UITour.showMenu(window, action.data.args);
|
|
break;
|
|
case "HIGHLIGHT_FEATURE":
|
|
const highlight = await UITour.getTarget(window, action.data.args);
|
|
if (highlight) {
|
|
await UITour.showHighlight(window, highlight, "none", {
|
|
autohide: true,
|
|
});
|
|
}
|
|
break;
|
|
case "INSTALL_ADDON_FROM_URL":
|
|
await this.installAddonFromURL(
|
|
browser,
|
|
action.data.url,
|
|
action.data.telemetrySource
|
|
);
|
|
break;
|
|
case "PIN_FIREFOX_TO_TASKBAR":
|
|
this.pinFirefoxToTaskbar(window);
|
|
break;
|
|
case "PIN_AND_DEFAULT":
|
|
this.pinFirefoxToTaskbar(window);
|
|
this.setDefaultBrowser(window);
|
|
break;
|
|
case "SET_DEFAULT_BROWSER":
|
|
this.setDefaultBrowser(window);
|
|
break;
|
|
case "PIN_CURRENT_TAB":
|
|
let tab = window.gBrowser.selectedTab;
|
|
window.gBrowser.pinTab(tab);
|
|
window.ConfirmationHint.show(tab, "pinTab", {
|
|
showDescription: true,
|
|
});
|
|
break;
|
|
case "SHOW_FIREFOX_ACCOUNTS":
|
|
const data = action.data;
|
|
const url = await FxAccounts.config.promiseConnectAccountURI(
|
|
(data && data.entrypoint) || "snippets",
|
|
(data && data.extraParams) || {}
|
|
);
|
|
// We want to replace the current tab.
|
|
window.openLinkIn(url, "current", {
|
|
private: false,
|
|
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal(
|
|
{}
|
|
),
|
|
csp: null,
|
|
});
|
|
break;
|
|
case "OPEN_PROTECTION_PANEL":
|
|
let { gProtectionsHandler } = window;
|
|
gProtectionsHandler.showProtectionsPopup({});
|
|
break;
|
|
case "OPEN_PROTECTION_REPORT":
|
|
window.gProtectionsHandler.openProtections();
|
|
break;
|
|
case "OPEN_AWESOME_BAR":
|
|
window.gURLBar.search("");
|
|
break;
|
|
case "DISABLE_STP_DOORHANGERS":
|
|
await this.blockMessageById([
|
|
"SOCIAL_TRACKING_PROTECTION",
|
|
"FINGERPRINTERS_PROTECTION",
|
|
"CRYPTOMINERS_PROTECTION",
|
|
]);
|
|
break;
|
|
case "DISABLE_DOH":
|
|
Services.prefs.setStringPref(
|
|
DOH_DOORHANGER_DECISION_PREF,
|
|
"UIDisabled"
|
|
);
|
|
Services.prefs.setIntPref(NETWORK_TRR_MODE_PREF, 5);
|
|
break;
|
|
case "ACCEPT_DOH":
|
|
Services.prefs.setStringPref(DOH_DOORHANGER_DECISION_PREF, "UIOk");
|
|
break;
|
|
case "CANCEL":
|
|
// A no-op used by CFRs that minimizes the notification but does not
|
|
// trigger a dismiss or block (it keeps the notification around)
|
|
break;
|
|
case "CONFIGURE_HOMEPAGE":
|
|
this.configureHomepage(action.data);
|
|
const topWindow = browser.ownerGlobal.window.BrowserWindowTracker.getTopWindow();
|
|
if (topWindow) {
|
|
topWindow.BrowserHome();
|
|
}
|
|
break;
|
|
case "ENABLE_TOTAL_COOKIE_PROTECTION":
|
|
Services.prefs.setBoolPref(
|
|
"privacy.restrict3rdpartystorage.rollout.enabledByDefault",
|
|
true
|
|
);
|
|
break;
|
|
case "ENABLE_TOTAL_COOKIE_PROTECTION_SECTION_AND_OPT_OUT":
|
|
Services.prefs.setBoolPref(
|
|
"privacy.restrict3rdpartystorage.rollout.enabledByDefault",
|
|
false
|
|
);
|
|
Services.prefs.setBoolPref(
|
|
"privacy.restrict3rdpartystorage.rollout.preferences.TCPToggleInStandard",
|
|
true
|
|
);
|
|
break;
|
|
default:
|
|
throw new Error(
|
|
`Special message action with type ${action.type} is unsupported.`
|
|
);
|
|
}
|
|
},
|
|
};
|