diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:42 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:42 +0000 |
commit | da4c7e7ed675c3bf405668739c3012d140856109 (patch) | |
tree | cdd868dba063fecba609a1d819de271f0d51b23e /browser/components/asrouter/modules | |
parent | Adding upstream version 125.0.3. (diff) | |
download | firefox-da4c7e7ed675c3bf405668739c3012d140856109.tar.xz firefox-da4c7e7ed675c3bf405668739c3012d140856109.zip |
Adding upstream version 126.0.upstream/126.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/components/asrouter/modules')
-rw-r--r-- | browser/components/asrouter/modules/ASRouter.sys.mjs | 47 | ||||
-rw-r--r-- | browser/components/asrouter/modules/ASRouterParentProcessMessageHandler.sys.mjs | 9 | ||||
-rw-r--r-- | browser/components/asrouter/modules/ASRouterTargeting.sys.mjs | 9 | ||||
-rw-r--r-- | browser/components/asrouter/modules/ActorConstants.mjs (renamed from browser/components/asrouter/modules/ActorConstants.sys.mjs) | 3 | ||||
-rw-r--r-- | browser/components/asrouter/modules/MomentsPageHub.sys.mjs | 2 | ||||
-rw-r--r-- | browser/components/asrouter/modules/OnboardingMessageProvider.sys.mjs | 100 | ||||
-rw-r--r-- | browser/components/asrouter/modules/PanelTestProvider.sys.mjs | 128 | ||||
-rw-r--r-- | browser/components/asrouter/modules/ToolbarBadgeHub.sys.mjs | 36 | ||||
-rw-r--r-- | browser/components/asrouter/modules/ToolbarPanelHub.sys.mjs | 544 |
9 files changed, 103 insertions, 775 deletions
diff --git a/browser/components/asrouter/modules/ASRouter.sys.mjs b/browser/components/asrouter/modules/ASRouter.sys.mjs index e46c57f685..b36a9023e1 100644 --- a/browser/components/asrouter/modules/ASRouter.sys.mjs +++ b/browser/components/asrouter/modules/ASRouter.sys.mjs @@ -55,7 +55,6 @@ ChromeUtils.defineESModuleGetters(lazy, { Spotlight: "resource:///modules/asrouter/Spotlight.sys.mjs", ToastNotification: "resource:///modules/asrouter/ToastNotification.sys.mjs", ToolbarBadgeHub: "resource:///modules/asrouter/ToolbarBadgeHub.sys.mjs", - ToolbarPanelHub: "resource:///modules/asrouter/ToolbarPanelHub.sys.mjs", }); XPCOMUtils.defineLazyServiceGetters(lazy, { @@ -67,7 +66,7 @@ ChromeUtils.defineLazyGetter(lazy, "log", () => { ); return new Logger("ASRouter"); }); -import { actionCreators as ac } from "resource://activity-stream/common/Actions.sys.mjs"; +import { actionCreators as ac } from "resource://activity-stream/common/Actions.mjs"; import { MESSAGING_EXPERIMENTS_DEFAULT_FEATURES } from "resource:///modules/asrouter/MessagingExperimentConstants.sys.mjs"; import { CFRMessageProvider } from "resource:///modules/asrouter/CFRMessageProvider.sys.mjs"; import { OnboardingMessageProvider } from "resource:///modules/asrouter/OnboardingMessageProvider.sys.mjs"; @@ -620,7 +619,6 @@ export class _ASRouter { this._onLocaleChanged = this._onLocaleChanged.bind(this); this.isUnblockedMessage = this.isUnblockedMessage.bind(this); this.unblockAll = this.unblockAll.bind(this); - this.forceWNPanel = this.forceWNPanel.bind(this); this._onExperimentEnrollmentsUpdated = this._onExperimentEnrollmentsUpdated.bind(this); this.forcePBWindow = this.forcePBWindow.bind(this); @@ -995,10 +993,6 @@ export class _ASRouter { unblockMessageById: this.unblockMessageById, sendTelemetry: this.sendTelemetry, }); - lazy.ToolbarPanelHub.init(this.waitForInitialized, { - getMessages: this.handleMessageRequest, - sendTelemetry: this.sendTelemetry, - }); lazy.MomentsPageHub.init(this.waitForInitialized, { handleMessageRequest: this.handleMessageRequest, addImpression: this.addImpression, @@ -1055,7 +1049,6 @@ export class _ASRouter { lazy.ASRouterPreferences.removeListener(this.onPrefChange); lazy.ASRouterPreferences.uninit(); - lazy.ToolbarPanelHub.uninit(); lazy.ToolbarBadgeHub.uninit(); lazy.MomentsPageHub.uninit(); @@ -1309,16 +1302,6 @@ export class _ASRouter { return true; } - async _extraTemplateStrings(originalMessage) { - let extraTemplateStrings; - let localProvider = this._findProvider(originalMessage.provider); - if (localProvider && localProvider.getExtraAttributes) { - extraTemplateStrings = await localProvider.getExtraAttributes(); - } - - return extraTemplateStrings; - } - _findProvider(providerID) { return this._localProviders[ this.state.providers.find(i => i.id === providerID).localProvider @@ -1346,11 +1329,6 @@ export class _ASRouter { } switch (message.template) { - case "whatsnew_panel_message": - if (force) { - lazy.ToolbarPanelHub.forceShowMessage(browser, message); - } - break; case "cfr_doorhanger": case "milestone_message": if (force) { @@ -2005,29 +1983,6 @@ export class _ASRouter { ); } - async forceWNPanel(browser) { - let win = browser.ownerGlobal; - await lazy.ToolbarPanelHub.enableToolbarButton(); - - win.PanelUI.showSubView( - "PanelUI-whatsNew", - win.document.getElementById("whats-new-menu-button") - ); - - let panel = win.document.getElementById("customizationui-widget-panel"); - // Set the attribute to keep the panel open - panel.setAttribute("noautohide", true); - } - - async closeWNPanel(browser) { - let win = browser.ownerGlobal; - let panel = win.document.getElementById("customizationui-widget-panel"); - // Set the attribute to allow the panel to close - panel.setAttribute("noautohide", false); - // Removing the button is enough to close the panel. - await lazy.ToolbarPanelHub._hideToolbarButton(win); - } - async _onExperimentEnrollmentsUpdated() { const experimentProvider = this.state.providers.find( p => p.id === "messaging-experiments" diff --git a/browser/components/asrouter/modules/ASRouterParentProcessMessageHandler.sys.mjs b/browser/components/asrouter/modules/ASRouterParentProcessMessageHandler.sys.mjs index c2f5fcd884..8aa4d7dbc9 100644 --- a/browser/components/asrouter/modules/ASRouterParentProcessMessageHandler.sys.mjs +++ b/browser/components/asrouter/modules/ASRouterParentProcessMessageHandler.sys.mjs @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { ASRouterPreferences } from "resource:///modules/asrouter/ASRouterPreferences.sys.mjs"; -import { MESSAGE_TYPE_HASH as msg } from "resource:///modules/asrouter/ActorConstants.sys.mjs"; +import { MESSAGE_TYPE_HASH as msg } from "resource:///modules/asrouter/ActorConstants.mjs"; export class ASRouterParentProcessMessageHandler { constructor({ @@ -27,7 +27,6 @@ export class ASRouterParentProcessMessageHandler { switch (type) { case msg.INFOBAR_TELEMETRY: case msg.TOOLBAR_BADGE_TELEMETRY: - case msg.TOOLBAR_PANEL_TELEMETRY: case msg.MOMENTS_PAGE_TELEMETRY: case msg.DOORHANGER_TELEMETRY: case msg.SPOTLIGHT_TELEMETRY: @@ -128,12 +127,6 @@ export class ASRouterParentProcessMessageHandler { case msg.FORCE_PRIVATE_BROWSING_WINDOW: { return this._router.forcePBWindow(browser, data.message); } - case msg.FORCE_WHATSNEW_PANEL: { - return this._router.forceWNPanel(browser); - } - case msg.CLOSE_WHATSNEW_PANEL: { - return this._router.closeWNPanel(browser); - } case msg.MODIFY_MESSAGE_JSON: { return this._router.routeCFRMessage(data.content, browser, data, true); } diff --git a/browser/components/asrouter/modules/ASRouterTargeting.sys.mjs b/browser/components/asrouter/modules/ASRouterTargeting.sys.mjs index d76b303fc6..9773eda270 100644 --- a/browser/components/asrouter/modules/ASRouterTargeting.sys.mjs +++ b/browser/components/asrouter/modules/ASRouterTargeting.sys.mjs @@ -74,12 +74,6 @@ XPCOMUtils.defineLazyPreferenceGetter( ); XPCOMUtils.defineLazyPreferenceGetter( lazy, - "isWhatsNewPanelEnabled", - "browser.messaging-system.whatsNewPanel.enabled", - false -); -XPCOMUtils.defineLazyPreferenceGetter( - lazy, "hasAccessedFxAPanel", "identity.fxaccounts.toolbar.accessed", false @@ -704,9 +698,6 @@ const TargetingGetters = { get hasAccessedFxAPanel() { return lazy.hasAccessedFxAPanel; }, - get isWhatsNewPanelEnabled() { - return lazy.isWhatsNewPanelEnabled; - }, get userPrefs() { return { cfrFeatures: lazy.cfrFeaturesUserPref, diff --git a/browser/components/asrouter/modules/ActorConstants.sys.mjs b/browser/components/asrouter/modules/ActorConstants.mjs index 4c996552ab..c1c18e006e 100644 --- a/browser/components/asrouter/modules/ActorConstants.sys.mjs +++ b/browser/components/asrouter/modules/ActorConstants.mjs @@ -12,7 +12,6 @@ export const MESSAGE_TYPE_LIST = [ "PBNEWTAB_MESSAGE_REQUEST", "DOORHANGER_TELEMETRY", "TOOLBAR_BADGE_TELEMETRY", - "TOOLBAR_PANEL_TELEMETRY", "MOMENTS_PAGE_TELEMETRY", "INFOBAR_TELEMETRY", "SPOTLIGHT_TELEMETRY", @@ -30,9 +29,7 @@ export const MESSAGE_TYPE_LIST = [ "EVALUATE_JEXL_EXPRESSION", "EXPIRE_QUERY_CACHE", "FORCE_ATTRIBUTION", - "FORCE_WHATSNEW_PANEL", "FORCE_PRIVATE_BROWSING_WINDOW", - "CLOSE_WHATSNEW_PANEL", "OVERRIDE_MESSAGE", "MODIFY_MESSAGE_JSON", "RESET_PROVIDER_PREF", diff --git a/browser/components/asrouter/modules/MomentsPageHub.sys.mjs b/browser/components/asrouter/modules/MomentsPageHub.sys.mjs index 84fee3b517..3a59e9d450 100644 --- a/browser/components/asrouter/modules/MomentsPageHub.sys.mjs +++ b/browser/components/asrouter/modules/MomentsPageHub.sys.mjs @@ -165,7 +165,7 @@ export class _MomentsPageHub { } /** - * ToolbarBadgeHub - singleton instance of _ToolbarBadgeHub that can initiate + * MomentsPageHub - singleton instance of _MomentsPageHub that can initiate * message requests and render messages. */ export const MomentsPageHub = new _MomentsPageHub(); diff --git a/browser/components/asrouter/modules/OnboardingMessageProvider.sys.mjs b/browser/components/asrouter/modules/OnboardingMessageProvider.sys.mjs index ceded6b755..3cfbbb3f34 100644 --- a/browser/components/asrouter/modules/OnboardingMessageProvider.sys.mjs +++ b/browser/components/asrouter/modules/OnboardingMessageProvider.sys.mjs @@ -1210,6 +1210,106 @@ const BASE_MESSAGES = () => [ id: "defaultBrowserCheck", }, }, + { + id: "SET_DEFAULT_BROWSER_GUIDANCE_NOTIFICATION_WIN10", + template: "toast_notification", + content: { + title: { + string_id: "default-browser-guidance-notification-title", + }, + body: { + string_id: + "default-browser-guidance-notification-body-instruction-win10", + }, + launch_action: { + type: "OPEN_URL", + data: { + args: "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/win-set-firefox-default-browser", + where: "tabshifted", + }, + }, + requireInteraction: true, + actions: [ + { + action: "info-page", + title: { + string_id: "default-browser-guidance-notification-info-page", + }, + launch_action: { + type: "OPEN_URL", + data: { + args: "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/win-set-firefox-default-browser", + where: "tabshifted", + }, + }, + }, + { + action: "dismiss", + title: { + string_id: "default-browser-guidance-notification-dismiss", + }, + windowsSystemActivationType: true, + }, + ], + tag: "set-default-guidance-notification", + }, + // Both Windows 10 and 11 return `os.windowsVersion == 10.0`. We limit to + // only Windows 10 with `os.windowsBuildNumber < 22000`. We need this due to + // Windows 10 and 11 having substantively different UX for Windows Settings. + targeting: + "os.isWindows && os.windowsVersion >= 10.0 && os.windowsBuildNumber < 22000", + trigger: { id: "deeplinkedToWindowsSettingsUI" }, + }, + { + id: "SET_DEFAULT_BROWSER_GUIDANCE_NOTIFICATION_WIN11", + template: "toast_notification", + content: { + title: { + string_id: "default-browser-guidance-notification-title", + }, + body: { + string_id: + "default-browser-guidance-notification-body-instruction-win11", + }, + launch_action: { + type: "OPEN_URL", + data: { + args: "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/win-set-firefox-default-browser", + where: "tabshifted", + }, + }, + requireInteraction: true, + actions: [ + { + action: "info-page", + title: { + string_id: "default-browser-guidance-notification-info-page", + }, + launch_action: { + type: "OPEN_URL", + data: { + args: "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/win-set-firefox-default-browser", + where: "tabshifted", + }, + }, + }, + { + action: "dismiss", + title: { + string_id: "default-browser-guidance-notification-dismiss", + }, + windowsSystemActivationType: true, + }, + ], + tag: "set-default-guidance-notification", + }, + // Both Windows 10 and 11 return `os.windowsVersion == 10.0`. We limit to + // only Windows 11 with `os.windowsBuildNumber >= 22000`. We need this due to + // Windows 10 and 11 having substantively different UX for Windows Settings. + targeting: + "os.isWindows && os.windowsVersion >= 10.0 && os.windowsBuildNumber >= 22000", + trigger: { id: "deeplinkedToWindowsSettingsUI" }, + }, ]; // Eventually, move Feature Callout messages to their own provider diff --git a/browser/components/asrouter/modules/PanelTestProvider.sys.mjs b/browser/components/asrouter/modules/PanelTestProvider.sys.mjs index 7a7ff1e1fc..5180e2e6a2 100644 --- a/browser/components/asrouter/modules/PanelTestProvider.sys.mjs +++ b/browser/components/asrouter/modules/PanelTestProvider.sys.mjs @@ -20,134 +20,6 @@ const MESSAGES = () => [ trigger: { id: "momentsUpdate" }, }, { - id: "WHATS_NEW_FINGERPRINTER_COUNTER_ALT", - template: "whatsnew_panel_message", - order: 6, - content: { - bucket_id: "WHATS_NEW_72", - published_date: 1574776601000, - title: "Title", - icon_url: - "chrome://activity-stream/content/data/content/assets/protection-report-icon.png", - icon_alt: { string_id: "cfr-badge-reader-label-newfeature" }, - body: "Message body", - link_text: "Click here", - cta_url: "about:blank", - cta_type: "OPEN_PROTECTION_REPORT", - }, - targeting: `firefoxVersion >= 72`, - trigger: { id: "whatsNewPanelOpened" }, - }, - { - id: "WHATS_NEW_70_1", - template: "whatsnew_panel_message", - order: 3, - content: { - bucket_id: "WHATS_NEW_70_1", - published_date: 1560969794394, - title: "Protection Is Our Focus", - icon_url: - "chrome://activity-stream/content/data/content/assets/whatsnew-send-icon.png", - icon_alt: "Firefox Send Logo", - body: "The New Enhanced Tracking Protection, gives you the best level of protection and performance. Discover how this version is the safest version of firefox ever made.", - cta_url: "https://blog.mozilla.org/", - cta_type: "OPEN_URL", - }, - targeting: `firefoxVersion > 69`, - trigger: { id: "whatsNewPanelOpened" }, - }, - { - id: "WHATS_NEW_70_2", - template: "whatsnew_panel_message", - order: 1, - content: { - bucket_id: "WHATS_NEW_70_1", - published_date: 1560969794394, - title: "Another thing new in Firefox 70", - body: "The New Enhanced Tracking Protection, gives you the best level of protection and performance. Discover how this version is the safest version of firefox ever made.", - link_text: "Learn more on our blog", - cta_url: "https://blog.mozilla.org/", - cta_type: "OPEN_URL", - }, - targeting: `firefoxVersion > 69`, - trigger: { id: "whatsNewPanelOpened" }, - }, - { - id: "WHATS_NEW_SEARCH_SHORTCUTS_84", - template: "whatsnew_panel_message", - order: 2, - content: { - bucket_id: "WHATS_NEW_SEARCH_SHORTCUTS_84", - published_date: 1560969794394, - title: "Title", - icon_url: "chrome://global/skin/icons/check.svg", - icon_alt: "", - body: "Message content", - cta_url: - "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/search-shortcuts", - cta_type: "OPEN_URL", - link_text: "Click here", - }, - targeting: "firefoxVersion >= 84", - trigger: { - id: "whatsNewPanelOpened", - }, - }, - { - id: "WHATS_NEW_PIONEER_82", - template: "whatsnew_panel_message", - order: 1, - content: { - bucket_id: "WHATS_NEW_PIONEER_82", - published_date: 1603152000000, - title: "Put your data to work for a better internet", - body: "Contribute your data to Mozilla's Pioneer program to help researchers understand pressing technology issues like misinformation, data privacy, and ethical AI.", - cta_url: "about:blank", - cta_where: "tab", - cta_type: "OPEN_ABOUT_PAGE", - link_text: "Join Pioneer", - }, - targeting: "firefoxVersion >= 82", - trigger: { - id: "whatsNewPanelOpened", - }, - }, - { - id: "WHATS_NEW_MEDIA_SESSION_82", - template: "whatsnew_panel_message", - order: 3, - content: { - bucket_id: "WHATS_NEW_MEDIA_SESSION_82", - published_date: 1603152000000, - title: "Title", - body: "Message content", - cta_url: - "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/media-keyboard-control", - cta_type: "OPEN_URL", - link_text: "Click here", - }, - targeting: "firefoxVersion >= 82", - trigger: { - id: "whatsNewPanelOpened", - }, - }, - { - id: "WHATS_NEW_69_1", - template: "whatsnew_panel_message", - order: 1, - content: { - bucket_id: "WHATS_NEW_69_1", - published_date: 1557346235089, - title: "Something new in Firefox 69", - body: "The New Enhanced Tracking Protection, gives you the best level of protection and performance. Discover how this version is the safest version of firefox ever made.", - link_text: "Learn more on our blog", - cta_url: "https://blog.mozilla.org/", - cta_type: "OPEN_URL", - }, - targeting: `firefoxVersion > 68`, - trigger: { id: "whatsNewPanelOpened" }, - }, - { id: "PERSONALIZED_CFR_MESSAGE", template: "cfr_doorhanger", groups: ["cfr"], diff --git a/browser/components/asrouter/modules/ToolbarBadgeHub.sys.mjs b/browser/components/asrouter/modules/ToolbarBadgeHub.sys.mjs index 57fd104f19..36f7ca5005 100644 --- a/browser/components/asrouter/modules/ToolbarBadgeHub.sys.mjs +++ b/browser/components/asrouter/modules/ToolbarBadgeHub.sys.mjs @@ -10,7 +10,6 @@ ChromeUtils.defineESModuleGetters(lazy, { clearTimeout: "resource://gre/modules/Timer.sys.mjs", requestIdleCallback: "resource://gre/modules/Timer.sys.mjs", setTimeout: "resource://gre/modules/Timer.sys.mjs", - ToolbarPanelHub: "resource:///modules/asrouter/ToolbarPanelHub.sys.mjs", }); let notificationsByWindow = new WeakMap(); @@ -19,9 +18,6 @@ export class _ToolbarBadgeHub { constructor() { this.id = "toolbar-badge-hub"; this.state = {}; - this.prefs = { - WHATSNEW_TOOLBAR_PANEL: "browser.messaging-system.whatsNewPanel.enabled", - }; this.removeAllNotifications = this.removeAllNotifications.bind(this); this.removeToolbarNotification = this.removeToolbarNotification.bind(this); this.addToolbarNotification = this.addToolbarNotification.bind(this); @@ -62,34 +58,12 @@ export class _ToolbarBadgeHub { triggerId: "toolbarBadgeUpdate", template: "toolbar_badge", }); - // Listen for pref changes that could trigger new badges - Services.prefs.addObserver(this.prefs.WHATSNEW_TOOLBAR_PANEL, this); - } - - observe(aSubject, aTopic, aPrefName) { - switch (aPrefName) { - case this.prefs.WHATSNEW_TOOLBAR_PANEL: - this.messageRequest({ - triggerId: "toolbarBadgeUpdate", - template: "toolbar_badge", - }); - break; - } } maybeInsertFTL(win) { win.MozXULElement.insertFTLIfNeeded("browser/newtab/asrouter.ftl"); } - executeAction({ id }) { - switch (id) { - case "show-whatsnew-button": - lazy.ToolbarPanelHub.enableToolbarButton(); - lazy.ToolbarPanelHub.enableAppmenuButton(); - break; - } - } - _clearBadgeTimeout() { if (this.state.showBadgeTimeoutId) { lazy.clearTimeout(this.state.showBadgeTimeoutId); @@ -153,9 +127,6 @@ export class _ToolbarBadgeHub { addToolbarNotification(win, message) { const document = win.browser.ownerDocument; - if (message.content.action) { - this.executeAction({ ...message.content.action, message_id: message.id }); - } let toolbarbutton = document.getElementById(message.content.target); if (toolbarbutton) { const badge = toolbarbutton.querySelector(".toolbarbutton-badge"); @@ -211,12 +182,6 @@ export class _ToolbarBadgeHub { } registerBadgeToAllWindows(message) { - if (message.template === "update_action") { - this.executeAction({ ...message.content.action, message_id: message.id }); - // No badge to set only an action to execute - return; - } - lazy.EveryWindow.registerCallback( this.id, win => { @@ -297,7 +262,6 @@ export class _ToolbarBadgeHub { this.state = {}; this._initialized = false; notificationsByWindow = new WeakMap(); - Services.prefs.removeObserver(this.prefs.WHATSNEW_TOOLBAR_PANEL, this); } } diff --git a/browser/components/asrouter/modules/ToolbarPanelHub.sys.mjs b/browser/components/asrouter/modules/ToolbarPanelHub.sys.mjs deleted file mode 100644 index 519bca8a89..0000000000 --- a/browser/components/asrouter/modules/ToolbarPanelHub.sys.mjs +++ /dev/null @@ -1,544 +0,0 @@ -/* 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/. */ - -const lazy = {}; - -// We use importESModule here instead of static import so that -// the Karma test environment won't choke on this module. This -// is because the Karma test environment already stubs out -// XPCOMUtils. That environment overrides importESModule to be a no-op -// (which can't be done for a static import statement). - -// eslint-disable-next-line mozilla/use-static-import -const { XPCOMUtils } = ChromeUtils.importESModule( - "resource://gre/modules/XPCOMUtils.sys.mjs" -); - -ChromeUtils.defineESModuleGetters(lazy, { - EveryWindow: "resource:///modules/EveryWindow.sys.mjs", - PanelMultiView: "resource:///modules/PanelMultiView.sys.mjs", - PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs", - SpecialMessageActions: - "resource://messaging-system/lib/SpecialMessageActions.sys.mjs", - RemoteL10n: "resource:///modules/asrouter/RemoteL10n.sys.mjs", -}); - -XPCOMUtils.defineLazyServiceGetter( - lazy, - "TrackingDBService", - "@mozilla.org/tracking-db-service;1", - "nsITrackingDBService" -); - -const idToTextMap = new Map([ - [Ci.nsITrackingDBService.TRACKERS_ID, "trackerCount"], - [Ci.nsITrackingDBService.TRACKING_COOKIES_ID, "cookieCount"], - [Ci.nsITrackingDBService.CRYPTOMINERS_ID, "cryptominerCount"], - [Ci.nsITrackingDBService.FINGERPRINTERS_ID, "fingerprinterCount"], - [Ci.nsITrackingDBService.SOCIAL_ID, "socialCount"], -]); - -const WHATSNEW_ENABLED_PREF = "browser.messaging-system.whatsNewPanel.enabled"; -const PROTECTIONS_PANEL_INFOMSG_PREF = - "browser.protections_panel.infoMessage.seen"; - -const TOOLBAR_BUTTON_ID = "whats-new-menu-button"; -const APPMENU_BUTTON_ID = "appMenu-whatsnew-button"; - -const BUTTON_STRING_ID = "cfr-whatsnew-button"; -const WHATS_NEW_PANEL_SELECTOR = "PanelUI-whatsNew-message-container"; - -export class _ToolbarPanelHub { - constructor() { - this.triggerId = "whatsNewPanelOpened"; - this._showAppmenuButton = this._showAppmenuButton.bind(this); - this._hideAppmenuButton = this._hideAppmenuButton.bind(this); - this._showToolbarButton = this._showToolbarButton.bind(this); - this._hideToolbarButton = this._hideToolbarButton.bind(this); - - this.state = {}; - this._initialized = false; - } - - async init(waitForInitialized, { getMessages, sendTelemetry }) { - if (this._initialized) { - return; - } - - this._initialized = true; - this._getMessages = getMessages; - this._sendTelemetry = sendTelemetry; - // Wait for ASRouter messages to become available in order to know - // if we can show the What's New panel - await waitForInitialized; - // Enable the application menu button so that the user can access - // the panel outside of the toolbar button - await this.enableAppmenuButton(); - - this.state = { - protectionPanelMessageSeen: Services.prefs.getBoolPref( - PROTECTIONS_PANEL_INFOMSG_PREF, - false - ), - }; - } - - uninit() { - this._initialized = false; - lazy.EveryWindow.unregisterCallback(TOOLBAR_BUTTON_ID); - lazy.EveryWindow.unregisterCallback(APPMENU_BUTTON_ID); - } - - get messages() { - return this._getMessages({ - template: "whatsnew_panel_message", - triggerId: "whatsNewPanelOpened", - returnAll: true, - }); - } - - toggleWhatsNewPref(event) { - // Checkbox onclick handler gets called before the checkbox state gets toggled, - // so we have to call it with the opposite value. - let newValue = !event.target.checked; - Services.prefs.setBoolPref(WHATSNEW_ENABLED_PREF, newValue); - - this.sendUserEventTelemetry( - event.target.ownerGlobal, - "WNP_PREF_TOGGLE", - // Message id is not applicable in this case, the notification state - // is not related to a particular message - { id: "n/a" }, - { value: { prefValue: newValue } } - ); - } - - maybeInsertFTL(win) { - win.MozXULElement.insertFTLIfNeeded("browser/newtab/asrouter.ftl"); - win.MozXULElement.insertFTLIfNeeded("toolkit/branding/brandings.ftl"); - win.MozXULElement.insertFTLIfNeeded("toolkit/branding/accounts.ftl"); - } - - maybeLoadCustomElement(win) { - if (!win.customElements.get("remote-text")) { - Services.scriptloader.loadSubScript( - "resource://activity-stream/data/custom-elements/paragraph.js", - win - ); - } - } - - // Turns on the Appmenu (hamburger menu) button for all open windows and future windows. - async enableAppmenuButton() { - if ((await this.messages).length) { - lazy.EveryWindow.registerCallback( - APPMENU_BUTTON_ID, - this._showAppmenuButton, - this._hideAppmenuButton - ); - } - } - - // Removes the button from the Appmenu. - // Only used in tests. - disableAppmenuButton() { - lazy.EveryWindow.unregisterCallback(APPMENU_BUTTON_ID); - } - - // Turns on the Toolbar button for all open windows and future windows. - async enableToolbarButton() { - if ((await this.messages).length) { - lazy.EveryWindow.registerCallback( - TOOLBAR_BUTTON_ID, - this._showToolbarButton, - this._hideToolbarButton - ); - } - } - - // When the panel is hidden we want to run some cleanup - _onPanelHidden(win) { - const panelContainer = win.document.getElementById( - "customizationui-widget-panel" - ); - // When the panel is hidden we want to remove any toolbar buttons that - // might have been added as an entry point to the panel - const removeToolbarButton = () => { - lazy.EveryWindow.unregisterCallback(TOOLBAR_BUTTON_ID); - }; - if (!panelContainer) { - return; - } - panelContainer.addEventListener("popuphidden", removeToolbarButton, { - once: true, - }); - } - - // Newer messages first and use `order` field to decide between messages - // with the same timestamp - _sortWhatsNewMessages(m1, m2) { - // Sort by published_date in descending order. - if (m1.content.published_date === m2.content.published_date) { - // Ascending order - return m1.order - m2.order; - } - if (m1.content.published_date > m2.content.published_date) { - return -1; - } - return 1; - } - - // Render what's new messages into the panel. - async renderMessages(win, doc, containerId, options = {}) { - // Set the checked status of the footer checkbox - let value = Services.prefs.getBoolPref(WHATSNEW_ENABLED_PREF); - let checkbox = win.document.getElementById("panelMenu-toggleWhatsNew"); - - checkbox.checked = value; - - this.maybeLoadCustomElement(win); - const messages = - (options.force && options.messages) || - (await this.messages).sort(this._sortWhatsNewMessages); - const container = lazy.PanelMultiView.getViewNode(doc, containerId); - - if (messages) { - // Targeting attribute state might have changed making new messages - // available and old messages invalid, we need to refresh - this.removeMessages(win, containerId); - let previousDate = 0; - // Get and store any variable part of the message content - this.state.contentArguments = await this._contentArguments(); - for (let message of messages) { - container.appendChild( - this._createMessageElements(win, doc, message, previousDate) - ); - previousDate = message.content.published_date; - } - } - - this._onPanelHidden(win); - - // Panel impressions are not associated with one particular message - // but with a set of messages. We concatenate message ids and send them - // back for every impression. - const eventId = { - id: messages - .map(({ id }) => id) - .sort() - .join(","), - }; - // Check `mainview` attribute to determine if the panel is shown as a - // subview (inside the application menu) or as a toolbar dropdown. - // https://searchfox.org/mozilla-central/rev/07f7390618692fa4f2a674a96b9b677df3a13450/browser/components/customizableui/PanelMultiView.jsm#1268 - const mainview = win.PanelUI.whatsNewPanel.hasAttribute("mainview"); - this.sendUserEventTelemetry(win, "IMPRESSION", eventId, { - value: { view: mainview ? "toolbar_dropdown" : "application_menu" }, - }); - } - - removeMessages(win, containerId) { - const doc = win.document; - const messageNodes = lazy.PanelMultiView.getViewNode( - doc, - containerId - ).querySelectorAll(".whatsNew-message"); - for (const messageNode of messageNodes) { - messageNode.remove(); - } - } - - /** - * Dispatch the action defined in the message and user telemetry event. - */ - _dispatchUserAction(win, message) { - let url; - try { - // Set platform specific path variables for SUMO articles - url = Services.urlFormatter.formatURL(message.content.cta_url); - } catch (e) { - console.error(e); - url = message.content.cta_url; - } - lazy.SpecialMessageActions.handleAction( - { - type: message.content.cta_type, - data: { - args: url, - where: message.content.cta_where || "tabshifted", - }, - }, - win.browser - ); - - this.sendUserEventTelemetry(win, "CLICK", message); - } - - /** - * Attach event listener to dispatch message defined action. - */ - _attachCommandListener(win, element, message) { - // Add event listener for `mouseup` not to overlap with the - // `mousedown` & `click` events dispatched from PanelMultiView.sys.mjs - // https://searchfox.org/mozilla-central/rev/7531325c8660cfa61bf71725f83501028178cbb9/browser/components/customizableui/PanelMultiView.jsm#1830-1837 - element.addEventListener("mouseup", () => { - this._dispatchUserAction(win, message); - }); - element.addEventListener("keyup", e => { - if (e.key === "Enter" || e.key === " ") { - this._dispatchUserAction(win, message); - } - }); - } - - _createMessageElements(win, doc, message, previousDate) { - const { content } = message; - const messageEl = lazy.RemoteL10n.createElement(doc, "div"); - messageEl.classList.add("whatsNew-message"); - - // Only render date if it is different from the one rendered before. - if (content.published_date !== previousDate) { - messageEl.appendChild( - lazy.RemoteL10n.createElement(doc, "p", { - classList: "whatsNew-message-date", - content: new Date(content.published_date).toLocaleDateString( - "default", - { - month: "long", - day: "numeric", - year: "numeric", - } - ), - }) - ); - } - - const wrapperEl = lazy.RemoteL10n.createElement(doc, "div"); - wrapperEl.doCommand = () => this._dispatchUserAction(win, message); - wrapperEl.classList.add("whatsNew-message-body"); - messageEl.appendChild(wrapperEl); - - if (content.icon_url) { - wrapperEl.classList.add("has-icon"); - const iconEl = lazy.RemoteL10n.createElement(doc, "img"); - iconEl.src = content.icon_url; - iconEl.classList.add("whatsNew-message-icon"); - if (content.icon_alt && content.icon_alt.string_id) { - doc.l10n.setAttributes(iconEl, content.icon_alt.string_id); - } else { - iconEl.setAttribute("alt", content.icon_alt); - } - wrapperEl.appendChild(iconEl); - } - - wrapperEl.appendChild(this._createMessageContent(win, doc, content)); - - if (content.link_text) { - const anchorEl = lazy.RemoteL10n.createElement(doc, "a", { - classList: "text-link", - content: content.link_text, - }); - anchorEl.doCommand = () => this._dispatchUserAction(win, message); - wrapperEl.appendChild(anchorEl); - } - - // Attach event listener on entire message container - this._attachCommandListener(win, messageEl, message); - - return messageEl; - } - - /** - * Return message title (optional subtitle) and body - */ - _createMessageContent(win, doc, content) { - const wrapperEl = new win.DocumentFragment(); - - wrapperEl.appendChild( - lazy.RemoteL10n.createElement(doc, "h2", { - classList: "whatsNew-message-title", - content: content.title, - attributes: this.state.contentArguments, - }) - ); - - wrapperEl.appendChild( - lazy.RemoteL10n.createElement(doc, "p", { - content: content.body, - classList: "whatsNew-message-content", - attributes: this.state.contentArguments, - }) - ); - - return wrapperEl; - } - - _createHeroElement(win, doc, message) { - this.maybeLoadCustomElement(win); - - const messageEl = lazy.RemoteL10n.createElement(doc, "div"); - messageEl.setAttribute("id", "protections-popup-message"); - messageEl.classList.add("whatsNew-hero-message"); - const wrapperEl = lazy.RemoteL10n.createElement(doc, "div"); - wrapperEl.classList.add("whatsNew-message-body"); - messageEl.appendChild(wrapperEl); - - wrapperEl.appendChild( - lazy.RemoteL10n.createElement(doc, "h2", { - classList: "whatsNew-message-title", - content: message.content.title, - }) - ); - wrapperEl.appendChild( - lazy.RemoteL10n.createElement(doc, "p", { - classList: "protections-popup-content", - content: message.content.body, - }) - ); - - if (message.content.link_text) { - let linkEl = lazy.RemoteL10n.createElement(doc, "a", { - classList: "text-link", - content: message.content.link_text, - }); - linkEl.disabled = true; - wrapperEl.appendChild(linkEl); - this._attachCommandListener(win, linkEl, message); - } else { - this._attachCommandListener(win, wrapperEl, message); - } - - return messageEl; - } - - async _contentArguments() { - const { defaultEngine } = Services.search; - // Between now and 6 weeks ago - const dateTo = new Date(); - const dateFrom = new Date(dateTo.getTime() - 42 * 24 * 60 * 60 * 1000); - const eventsByDate = await lazy.TrackingDBService.getEventsByDateRange( - dateFrom, - dateTo - ); - // Make sure we set all types of possible values to 0 because they might - // be referenced by fluent strings - let totalEvents = { blockedCount: 0 }; - for (let blockedType of idToTextMap.values()) { - totalEvents[blockedType] = 0; - } - // Count all events in the past 6 weeks. Returns an object with: - // `blockedCount` total number of blocked resources - // {tracker|cookie|social...} breakdown by event type as defined by `idToTextMap` - totalEvents = eventsByDate.reduce((acc, day) => { - const type = day.getResultByName("type"); - const count = day.getResultByName("count"); - acc[idToTextMap.get(type)] = (acc[idToTextMap.get(type)] || 0) + count; - acc.blockedCount += count; - return acc; - }, totalEvents); - return { - // Keys need to match variable names used in asrouter.ftl - // `earliestDate` will be either 6 weeks ago or when tracking recording - // started. Whichever is more recent. - earliestDate: Math.max( - new Date(await lazy.TrackingDBService.getEarliestRecordedDate()), - dateFrom - ), - ...totalEvents, - // Passing in `undefined` as string for the Fluent variable name - // in order to match and select the message that does not require - // the variable. - searchEngineName: defaultEngine ? defaultEngine.name : "undefined", - }; - } - - async _showAppmenuButton(win) { - this.maybeInsertFTL(win); - await this._showElement( - win.browser.ownerDocument, - APPMENU_BUTTON_ID, - BUTTON_STRING_ID - ); - } - - _hideAppmenuButton(win, windowClosed) { - // No need to do something if the window is going away - if (!windowClosed) { - this._hideElement(win.browser.ownerDocument, APPMENU_BUTTON_ID); - } - } - - _showToolbarButton(win) { - const document = win.browser.ownerDocument; - this.maybeInsertFTL(win); - return this._showElement(document, TOOLBAR_BUTTON_ID, BUTTON_STRING_ID); - } - - _hideToolbarButton(win) { - this._hideElement(win.browser.ownerDocument, TOOLBAR_BUTTON_ID); - } - - _showElement(document, id, string_id) { - const el = lazy.PanelMultiView.getViewNode(document, id); - document.l10n.setAttributes(el, string_id); - el.hidden = false; - } - - _hideElement(document, id) { - const el = lazy.PanelMultiView.getViewNode(document, id); - if (el) { - el.hidden = true; - } - } - - _sendPing(ping) { - this._sendTelemetry({ - type: "TOOLBAR_PANEL_TELEMETRY", - data: { action: "whats-new-panel_user_event", ...ping }, - }); - } - - sendUserEventTelemetry(win, event, message, options = {}) { - // Only send pings for non private browsing windows - if ( - win && - !lazy.PrivateBrowsingUtils.isBrowserPrivate( - win.ownerGlobal.gBrowser.selectedBrowser - ) - ) { - this._sendPing({ - message_id: message.id, - event, - event_context: options.value, - }); - } - } - - /** - * @param {object} [browser] MessageChannel target argument as a response to a - * user action. No message is shown if undefined. - * @param {object[]} messages Messages selected from devtools page - */ - forceShowMessage(browser, messages) { - if (!browser) { - return; - } - const win = browser.ownerGlobal; - const doc = browser.ownerDocument; - this.removeMessages(win, WHATS_NEW_PANEL_SELECTOR); - this.renderMessages(win, doc, WHATS_NEW_PANEL_SELECTOR, { - force: true, - messages: Array.isArray(messages) ? messages : [messages], - }); - win.PanelUI.panel.addEventListener("popuphidden", event => - this.removeMessages(event.target.ownerGlobal, WHATS_NEW_PANEL_SELECTOR) - ); - } -} - -/** - * ToolbarPanelHub - singleton instance of _ToolbarPanelHub that can initiate - * message requests and render messages. - */ -export const ToolbarPanelHub = new _ToolbarPanelHub(); |