diff options
Diffstat (limited to 'browser/components/urlbar/QuickActionsLoaderDefault.sys.mjs')
-rw-r--r-- | browser/components/urlbar/QuickActionsLoaderDefault.sys.mjs | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/browser/components/urlbar/QuickActionsLoaderDefault.sys.mjs b/browser/components/urlbar/QuickActionsLoaderDefault.sys.mjs new file mode 100644 index 0000000000..ff0d88228a --- /dev/null +++ b/browser/components/urlbar/QuickActionsLoaderDefault.sys.mjs @@ -0,0 +1,297 @@ +/* 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/. */ + +import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + DevToolsShim: "chrome://devtools-startup/content/DevToolsShim.sys.mjs", + ResetProfile: "resource://gre/modules/ResetProfile.sys.mjs", + UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs", + UrlbarProviderQuickActions: + "resource:///modules/UrlbarProviderQuickActions.sys.mjs", +}); + +import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; + +XPCOMUtils.defineLazyModuleGetters(lazy, { + BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm", + ClientEnvironment: "resource://normandy/lib/ClientEnvironment.jsm", +}); + +if (AppConstants.MOZ_UPDATER) { + XPCOMUtils.defineLazyServiceGetter( + lazy, + "AUS", + "@mozilla.org/updates/update-service;1", + "nsIApplicationUpdateService" + ); +} + +let openUrlFun = url => () => openUrl(url); +let openUrl = url => { + let window = lazy.BrowserWindowTracker.getTopWindow(); + + if (url.startsWith("about:")) { + window.switchToTabHavingURI(Services.io.newURI(url), true, { + ignoreFragment: "whenComparing", + }); + } else { + window.gBrowser.addTab(url, { + inBackground: false, + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), + }); + } + return { focusContent: true }; +}; + +let openAddonsUrl = url => { + return () => { + let window = lazy.BrowserWindowTracker.getTopWindow(); + window.BrowserOpenAddonsMgr(url, { selectTabByViewId: true }); + }; +}; + +let currentBrowser = () => + lazy.BrowserWindowTracker.getTopWindow()?.gBrowser.selectedBrowser; +let currentTab = () => + lazy.BrowserWindowTracker.getTopWindow()?.gBrowser.selectedTab; + +XPCOMUtils.defineLazyGetter(lazy, "gFluentStrings", function() { + return new Localization(["branding/brand.ftl", "browser/browser.ftl"], true); +}); + +const DEFAULT_ACTIONS = { + addons: { + l10nCommands: ["quickactions-cmd-addons2", "quickactions-addons"], + icon: "chrome://mozapps/skin/extensions/category-extensions.svg", + label: "quickactions-addons", + onPick: openAddonsUrl("addons://discover/"), + }, + bookmarks: { + l10nCommands: ["quickactions-cmd-bookmarks", "quickactions-bookmarks2"], + icon: "chrome://browser/skin/bookmark.svg", + label: "quickactions-bookmarks2", + onPick: () => { + lazy.BrowserWindowTracker.getTopWindow().top.PlacesCommandHook.showPlacesOrganizer( + "BookmarksToolbar" + ); + }, + }, + clear: { + l10nCommands: [ + "quickactions-cmd-clearhistory", + "quickactions-clearhistory", + ], + label: "quickactions-clearhistory", + onPick: () => { + lazy.BrowserWindowTracker.getTopWindow() + .document.getElementById("Tools:Sanitize") + .doCommand(); + }, + }, + downloads: { + l10nCommands: ["quickactions-cmd-downloads", "quickactions-downloads2"], + icon: "chrome://browser/skin/downloads/downloads.svg", + label: "quickactions-downloads2", + onPick: openUrlFun("about:downloads"), + }, + extensions: { + l10nCommands: ["quickactions-cmd-extensions", "quickactions-extensions"], + icon: "chrome://mozapps/skin/extensions/category-extensions.svg", + label: "quickactions-extensions", + onPick: openAddonsUrl("addons://list/extension"), + }, + inspect: { + l10nCommands: ["quickactions-cmd-inspector", "quickactions-inspector2"], + icon: "chrome://devtools/skin/images/open-inspector.svg", + label: "quickactions-inspector2", + isVisible: () => + lazy.DevToolsShim.isEnabled() || lazy.DevToolsShim.isDevToolsUser(), + isActive: () => { + // The inspect action is available if: + // 1. DevTools is enabled. + // 2. The user can be considered as a DevTools user. + // 3. The url is not about:devtools-toolbox. + // 4. The inspector is not opened yet on the page. + return ( + lazy.DevToolsShim.isEnabled() && + lazy.DevToolsShim.isDevToolsUser() && + !currentBrowser()?.currentURI.spec.startsWith( + "about:devtools-toolbox" + ) && + !lazy.DevToolsShim.hasToolboxForTab(currentTab()) + ); + }, + onPick: openInspector, + }, + logins: { + l10nCommands: ["quickactions-cmd-logins", "quickactions-logins2"], + label: "quickactions-logins2", + onPick: openUrlFun("about:logins"), + }, + plugins: { + l10nCommands: ["quickactions-cmd-plugins", "quickactions-plugins"], + icon: "chrome://mozapps/skin/extensions/category-extensions.svg", + label: "quickactions-plugins", + onPick: openAddonsUrl("addons://list/plugin"), + }, + print: { + l10nCommands: ["quickactions-cmd-print", "quickactions-print2"], + label: "quickactions-print2", + icon: "chrome://global/skin/icons/print.svg", + onPick: () => { + lazy.BrowserWindowTracker.getTopWindow() + .document.getElementById("cmd_print") + .doCommand(); + }, + }, + private: { + l10nCommands: ["quickactions-cmd-private", "quickactions-private2"], + label: "quickactions-private2", + icon: "chrome://global/skin/icons/indicator-private-browsing.svg", + onPick: () => { + lazy.BrowserWindowTracker.getTopWindow().OpenBrowserWindow({ + private: true, + }); + }, + }, + refresh: { + l10nCommands: ["quickactions-cmd-refresh", "quickactions-refresh"], + label: "quickactions-refresh", + onPick: () => { + lazy.ResetProfile.openConfirmationDialog( + lazy.BrowserWindowTracker.getTopWindow() + ); + }, + }, + restart: { + l10nCommands: ["quickactions-cmd-restart", "quickactions-restart"], + label: "quickactions-restart", + onPick: restartBrowser, + }, + screenshot: { + l10nCommands: ["quickactions-cmd-screenshot", "quickactions-screenshot3"], + label: "quickactions-screenshot3", + icon: "chrome://browser/skin/screenshot.svg", + isActive: () => { + return !lazy.BrowserWindowTracker.getTopWindow().gScreenshots.shouldScreenshotsButtonBeDisabled(); + }, + onPick: () => { + lazy.BrowserWindowTracker.getTopWindow() + .document.getElementById("Browser:Screenshot") + .doCommand(); + return { focusContent: true }; + }, + }, + settings: { + l10nCommands: ["quickactions-cmd-settings", "quickactions-settings2"], + icon: "chrome://global/skin/icons/settings.svg", + label: "quickactions-settings2", + onPick: openUrlFun("about:preferences"), + }, + themes: { + l10nCommands: ["quickactions-cmd-themes", "quickactions-themes"], + icon: "chrome://mozapps/skin/extensions/category-extensions.svg", + label: "quickactions-themes", + onPick: openAddonsUrl("addons://list/theme"), + }, + update: { + l10nCommands: ["quickactions-cmd-update", "quickactions-update"], + label: "quickactions-update", + isActive: () => { + if (!AppConstants.MOZ_UPDATER) { + return false; + } + return ( + lazy.AUS.currentState == Ci.nsIApplicationUpdateService.STATE_PENDING + ); + }, + onPick: restartBrowser, + }, + viewsource: { + l10nCommands: ["quickactions-cmd-viewsource", "quickactions-viewsource2"], + icon: "chrome://global/skin/icons/settings.svg", + label: "quickactions-viewsource2", + isActive: () => currentBrowser()?.currentURI.scheme !== "view-source", + onPick: () => openUrl("view-source:" + currentBrowser().currentURI.spec), + }, +}; + +function openInspector() { + lazy.DevToolsShim.showToolboxForTab( + lazy.BrowserWindowTracker.getTopWindow().gBrowser.selectedTab, + { toolId: "inspector" } + ); +} + +// TODO: We likely want a prompt to confirm with the user that they want to restart +// the browser. +function restartBrowser() { + // Notify all windows that an application quit has been requested. + let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance( + Ci.nsISupportsPRBool + ); + Services.obs.notifyObservers( + cancelQuit, + "quit-application-requested", + "restart" + ); + // Something aborted the quit process. + if (cancelQuit.data) { + return; + } + // If already in safe mode restart in safe mode. + if (Services.appinfo.inSafeMode) { + Services.startup.restartInSafeMode(Ci.nsIAppStartup.eAttemptQuit); + } else { + Services.startup.quit( + Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart + ); + } +} + +function random(seed) { + let x = Math.sin(seed) * 10000; + return x - Math.floor(x); +} + +function shuffle(array, seed) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(random(seed) * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } +} + +/** + * Loads the default QuickActions. + */ +export class QuickActionsLoaderDefault { + static async load() { + let keys = Object.keys(DEFAULT_ACTIONS); + if (lazy.UrlbarPrefs.get("quickactions.randomOrderActions")) { + // We insert the actions in a random order which means they will be returned + // in a random but consistent order (the order of results for "view" and "views" + // should be the same). + // We use the Nimbus randomizationId as the seed as the order should not change + // for the user between restarts, it should be random between users but a user should + // see actions the same order. + let seed = [...lazy.ClientEnvironment.randomizationId] + .map(x => x.charCodeAt(0)) + .reduce((sum, a) => sum + a, 0); + shuffle(keys, seed); + } + for (const key of keys) { + let actionData = DEFAULT_ACTIONS[key]; + let messages = await lazy.gFluentStrings.formatMessages( + actionData.l10nCommands.map(id => ({ id })) + ); + actionData.commands = messages + .map(({ value }) => value.split(",").map(x => x.trim().toLowerCase())) + .flat(); + lazy.UrlbarProviderQuickActions.addAction(key, actionData); + } + } +} |