mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1724300 - Remove What's New Panel, ToolbarPanelHub components & related tests & references r=desktop-theme-reviewers,omc-reviewers,aminomancer,pdahiya,emilio,devtools-reviewers,firefox-desktop-core-reviewers ,home-newtab-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D201867
This commit is contained in:
parent
d9fed649f4
commit
079ff41016
@ -1705,7 +1705,6 @@ pref("browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts",
|
||||
|
||||
// ASRouter provider configuration
|
||||
pref("browser.newtabpage.activity-stream.asrouter.providers.cfr", "{\"id\":\"cfr\",\"enabled\":true,\"type\":\"remote-settings\",\"collection\":\"cfr\",\"updateCycleInMs\":3600000}");
|
||||
pref("browser.newtabpage.activity-stream.asrouter.providers.whats-new-panel", "{\"id\":\"whats-new-panel\",\"enabled\":false,\"type\":\"remote-settings\",\"collection\":\"whats-new-panel\",\"updateCycleInMs\":3600000}");
|
||||
pref("browser.newtabpage.activity-stream.asrouter.providers.message-groups", "{\"id\":\"message-groups\",\"enabled\":true,\"type\":\"remote-settings\",\"collection\":\"message-groups\",\"updateCycleInMs\":3600000}");
|
||||
pref("browser.newtabpage.activity-stream.asrouter.providers.messaging-experiments", "{\"id\":\"messaging-experiments\",\"enabled\":true,\"type\":\"remote-experiments\",\"updateCycleInMs\":3600000}");
|
||||
|
||||
@ -1817,9 +1816,6 @@ pref("browser.aboutwelcome.screens", "");
|
||||
// Used to enable window modal onboarding
|
||||
pref("browser.aboutwelcome.showModal", false);
|
||||
|
||||
// The pref that controls if the What's New panel is enabled.
|
||||
pref("browser.messaging-system.whatsNewPanel.enabled", true);
|
||||
|
||||
// Experiment Manager
|
||||
// See Console.sys.mjs LOG_LEVELS for all possible values
|
||||
pref("messaging-system.log", "warn");
|
||||
|
@ -3,16 +3,6 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
<html:template id="appMenu-viewCache">
|
||||
<panelview id="appMenu-mainView" class="PanelUI-subView">
|
||||
<vbox class="panel-subview-body">
|
||||
<toolbarbutton id="appMenu-whatsnew-button"
|
||||
class="subviewbutton subviewbutton-iconic subviewbutton-nav"
|
||||
hidden="true"
|
||||
closemenu="none"
|
||||
oncommand="PanelUI.showSubView('PanelUI-whatsNew', this)"/>
|
||||
</vbox>
|
||||
</panelview>
|
||||
|
||||
<!-- This is a placeholder app menu which should be replaced with the "real"
|
||||
Proton app menu before the Proton pref starts getting enabled. -->
|
||||
<panelview id="appMenu-protonMainView" class="PanelUI-subView"
|
||||
@ -759,29 +749,6 @@
|
||||
</vbox>
|
||||
</panelview>
|
||||
|
||||
<panelview id="PanelUI-whatsNew" class="PanelUI-subView" mainview-with-header="true">
|
||||
<hbox id="PanelUI-whatsNew-title" class="panel-header">
|
||||
<html:h1>
|
||||
<html:span data-l10n-id="whatsnew-panel-header"></html:span>
|
||||
</html:h1>
|
||||
</hbox>
|
||||
<toolbarseparator/>
|
||||
<vbox class="panel-subview-body">
|
||||
<toolbaritem id="PanelUI-whatsNew-content"
|
||||
orient="vertical"
|
||||
smoothscroll="false">
|
||||
<html:div id="PanelUI-whatsNew-message-container" role="document">
|
||||
<!-- What's New messages will be rendered here -->
|
||||
</html:div>
|
||||
</toolbaritem>
|
||||
</vbox>
|
||||
<toolbarseparator/>
|
||||
<checkbox id="panelMenu-toggleWhatsNew"
|
||||
class="panelMenu-toggleWhatsNew-checkbox"
|
||||
onclick="ToolbarPanelHub.toggleWhatsNewPref(event)"
|
||||
data-l10n-id="whatsnew-panel-footer-checkbox"/>
|
||||
</panelview>
|
||||
|
||||
<panelview id="reset-pbm-panel" class="PanelUI-subView" role="document">
|
||||
<vbox id="reset-pbm-panel-container" role="alertdialog" aria-labelledby="reset-pbm-panel-header">
|
||||
<hbox id="reset-pbm-panel-header">
|
||||
|
@ -2529,12 +2529,12 @@ var gProtectionsHandler = {
|
||||
};
|
||||
|
||||
const doc = event.target.ownerDocument;
|
||||
const container = doc.getElementById("messaging-system-message-container");
|
||||
const container = doc.getElementById("info-message-container");
|
||||
const infoButton = doc.getElementById("protections-popup-info-button");
|
||||
const panelContainer = doc.getElementById("protections-popup");
|
||||
const toggleMessage = () => {
|
||||
const learnMoreLink = doc.querySelector(
|
||||
"#messaging-system-message-container .text-link"
|
||||
"#info-message-container .text-link"
|
||||
);
|
||||
if (learnMoreLink) {
|
||||
container.toggleAttribute("disabled");
|
||||
|
@ -250,8 +250,7 @@ toolbar[customizing] > .overflow-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
toolbar[customizing] #ion-button,
|
||||
toolbar[customizing] #whats-new-menu-button {
|
||||
toolbar[customizing] #ion-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -491,13 +491,6 @@
|
||||
tooltiptext="Ion"
|
||||
onmousedown="switchToTabHavingURI('about:ion', true);"
|
||||
onkeypress="switchToTabHavingURI('about:ion', true);"/>
|
||||
<toolbarbutton id="whats-new-menu-button"
|
||||
class="toolbarbutton-1"
|
||||
delegatesanchor="true"
|
||||
hidden="true"
|
||||
badged="true"
|
||||
onmousedown="PanelUI.showSubView('PanelUI-whatsNew', this, event);"
|
||||
onkeypress="PanelUI.showSubView('PanelUI-whatsNew', this, event);"/>
|
||||
<toolbarbutton id="PanelUI-menu-button"
|
||||
class="toolbarbutton-1"
|
||||
delegatesanchor="true"
|
||||
|
@ -51,10 +51,10 @@ add_task(async function testPanelInfoMessage() {
|
||||
});
|
||||
|
||||
// Test that the info message is displayed when the panel opens
|
||||
let container = document.getElementById("messaging-system-message-container");
|
||||
let container = document.getElementById("info-message-container");
|
||||
let message = document.getElementById("protections-popup-message");
|
||||
let learnMoreLink = document.querySelector(
|
||||
"#messaging-system-message-container .text-link"
|
||||
"#info-message-container .text-link"
|
||||
);
|
||||
|
||||
// Check the visibility of the info message.
|
||||
|
@ -4462,14 +4462,6 @@ BrowserGlue.prototype = {
|
||||
|
||||
// Check the default branch as enterprise policies can set prefs there.
|
||||
const defaultPrefs = Services.prefs.getDefaultBranch("");
|
||||
if (
|
||||
!defaultPrefs.getBoolPref(
|
||||
"browser.messaging-system.whatsNewPanel.enabled",
|
||||
true
|
||||
)
|
||||
) {
|
||||
return "no-whatsNew";
|
||||
}
|
||||
if (!defaultPrefs.getBoolPref("browser.aboutwelcome.enabled", true)) {
|
||||
return "no-welcome";
|
||||
}
|
||||
|
@ -101,8 +101,6 @@ export class ASRouterChild extends JSWindowActorChild {
|
||||
case msg.DISABLE_PROVIDER:
|
||||
case msg.ENABLE_PROVIDER:
|
||||
case msg.EXPIRE_QUERY_CACHE:
|
||||
case msg.FORCE_WHATSNEW_PANEL:
|
||||
case msg.CLOSE_WHATSNEW_PANEL:
|
||||
case msg.FORCE_PRIVATE_BROWSING_WINDOW:
|
||||
case msg.IMPRESSION:
|
||||
case msg.RESET_PROVIDER_PREF:
|
||||
|
@ -126,10 +126,6 @@ async function getMessageValidators(skipValidation) {
|
||||
"./content-src/templates/OnboardingMessage/UpdateAction.schema.json",
|
||||
{ common: true }
|
||||
),
|
||||
whatsnew_panel_message: await getValidator(
|
||||
"./content-src/templates/OnboardingMessage/WhatsNewMessage.schema.json",
|
||||
{ common: true }
|
||||
),
|
||||
feature_callout: await getValidator(
|
||||
// For now, Feature Callout and Spotlight share a common schema
|
||||
"./content-src/templates/OnboardingMessage/Spotlight.schema.json",
|
||||
|
@ -982,89 +982,6 @@
|
||||
},
|
||||
"required": ["targeting"]
|
||||
},
|
||||
"WhatsNewMessage": {
|
||||
"$schema": "https://json-schema.org/draft/2019-09/schema",
|
||||
"$id": "file:///WhatsNewMessage.schema.json",
|
||||
"title": "WhatsNewMessage",
|
||||
"description": "A template for the messages that appear in the What's New panel.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "chrome://browser/content/asrouter/schemas/MessagingExperiment.schema.json#/$defs/Message"
|
||||
}
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"content": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"layout": {
|
||||
"description": "Different message layouts",
|
||||
"enum": ["tracking-protections"]
|
||||
},
|
||||
"bucket_id": {
|
||||
"type": "string",
|
||||
"description": "A bucket identifier for the addon. This is used in order to anonymize telemetry for history-sensitive targeting."
|
||||
},
|
||||
"published_date": {
|
||||
"type": "integer",
|
||||
"description": "The date/time (number of milliseconds elapsed since January 1, 1970 00:00:00 UTC) the message was published."
|
||||
},
|
||||
"title": {
|
||||
"$ref": "chrome://browser/content/asrouter/schemas/MessagingExperiment.schema.json#/$defs/localizableText",
|
||||
"description": "Id of localized string or message override of What's New message title"
|
||||
},
|
||||
"subtitle": {
|
||||
"$ref": "chrome://browser/content/asrouter/schemas/MessagingExperiment.schema.json#/$defs/localizableText",
|
||||
"description": "Id of localized string or message override of What's New message subtitle"
|
||||
},
|
||||
"body": {
|
||||
"$ref": "chrome://browser/content/asrouter/schemas/MessagingExperiment.schema.json#/$defs/localizableText",
|
||||
"description": "Id of localized string or message override of What's New message body"
|
||||
},
|
||||
"link_text": {
|
||||
"$ref": "chrome://browser/content/asrouter/schemas/MessagingExperiment.schema.json#/$defs/localizableText",
|
||||
"description": "(optional) Id of localized string or message override of What's New message link text"
|
||||
},
|
||||
"cta_url": {
|
||||
"description": "Target URL for the What's New message.",
|
||||
"type": "string",
|
||||
"format": "moz-url-format"
|
||||
},
|
||||
"cta_type": {
|
||||
"description": "Type of url open action",
|
||||
"enum": ["OPEN_URL", "OPEN_ABOUT_PAGE", "OPEN_PROTECTION_REPORT"]
|
||||
},
|
||||
"cta_where": {
|
||||
"description": "How to open the cta: new window, tab, focused, unfocused.",
|
||||
"enum": ["current", "tabshifted", "tab", "save", "window"]
|
||||
},
|
||||
"icon_url": {
|
||||
"description": "(optional) URL for the What's New message icon.",
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"icon_alt": {
|
||||
"$ref": "chrome://browser/content/asrouter/schemas/MessagingExperiment.schema.json#/$defs/localizableText",
|
||||
"description": "Alt text for image."
|
||||
}
|
||||
},
|
||||
"additionalProperties": true,
|
||||
"required": [
|
||||
"published_date",
|
||||
"title",
|
||||
"body",
|
||||
"cta_url",
|
||||
"bucket_id"
|
||||
]
|
||||
},
|
||||
"template": {
|
||||
"type": "string",
|
||||
"const": "whatsnew_panel_message"
|
||||
}
|
||||
},
|
||||
"required": ["order"],
|
||||
"additionalProperties": true
|
||||
},
|
||||
"Message": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -1093,8 +1010,7 @@
|
||||
"feature_callout",
|
||||
"toast_notification",
|
||||
"toolbar_badge",
|
||||
"update_action",
|
||||
"whatsnew_panel_message"
|
||||
"update_action"
|
||||
]
|
||||
},
|
||||
"frequency": {
|
||||
@ -1326,21 +1242,6 @@
|
||||
"then": {
|
||||
"$ref": "chrome://browser/content/asrouter/schemas/MessagingExperiment.schema.json#/$defs/UpdateAction"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"template": {
|
||||
"type": "string",
|
||||
"enum": ["whatsnew_panel_message"]
|
||||
}
|
||||
},
|
||||
"required": ["template"]
|
||||
},
|
||||
"then": {
|
||||
"$ref": "chrome://browser/content/asrouter/schemas/MessagingExperiment.schema.json#/$defs/WhatsNewMessage"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -83,9 +83,6 @@ SCHEMAS = [
|
||||
"UpdateAction": (
|
||||
SCHEMA_DIR / "OnboardingMessage" / "UpdateAction.schema.json"
|
||||
),
|
||||
"WhatsNewMessage": (
|
||||
SCHEMA_DIR / "OnboardingMessage" / "WhatsNewMessage.schema.json"
|
||||
),
|
||||
},
|
||||
bundle_common=True,
|
||||
test_corpus={
|
||||
|
@ -1,73 +0,0 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2019-09/schema",
|
||||
"$id": "file:///WhatsNewMessage.schema.json",
|
||||
"title": "WhatsNewMessage",
|
||||
"description": "A template for the messages that appear in the What's New panel.",
|
||||
"allOf": [{ "$ref": "file:///FxMSCommon.schema.json#/$defs/Message" }],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"content": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"layout": {
|
||||
"description": "Different message layouts",
|
||||
"enum": ["tracking-protections"]
|
||||
},
|
||||
"bucket_id": {
|
||||
"type": "string",
|
||||
"description": "A bucket identifier for the addon. This is used in order to anonymize telemetry for history-sensitive targeting."
|
||||
},
|
||||
"published_date": {
|
||||
"type": "integer",
|
||||
"description": "The date/time (number of milliseconds elapsed since January 1, 1970 00:00:00 UTC) the message was published."
|
||||
},
|
||||
"title": {
|
||||
"$ref": "file:///FxMSCommon.schema.json#/$defs/localizableText",
|
||||
"description": "Id of localized string or message override of What's New message title"
|
||||
},
|
||||
"subtitle": {
|
||||
"$ref": "file:///FxMSCommon.schema.json#/$defs/localizableText",
|
||||
"description": "Id of localized string or message override of What's New message subtitle"
|
||||
},
|
||||
"body": {
|
||||
"$ref": "file:///FxMSCommon.schema.json#/$defs/localizableText",
|
||||
"description": "Id of localized string or message override of What's New message body"
|
||||
},
|
||||
"link_text": {
|
||||
"$ref": "file:///FxMSCommon.schema.json#/$defs/localizableText",
|
||||
"description": "(optional) Id of localized string or message override of What's New message link text"
|
||||
},
|
||||
"cta_url": {
|
||||
"description": "Target URL for the What's New message.",
|
||||
"type": "string",
|
||||
"format": "moz-url-format"
|
||||
},
|
||||
"cta_type": {
|
||||
"description": "Type of url open action",
|
||||
"enum": ["OPEN_URL", "OPEN_ABOUT_PAGE", "OPEN_PROTECTION_REPORT"]
|
||||
},
|
||||
"cta_where": {
|
||||
"description": "How to open the cta: new window, tab, focused, unfocused.",
|
||||
"enum": ["current", "tabshifted", "tab", "save", "window"]
|
||||
},
|
||||
"icon_url": {
|
||||
"description": "(optional) URL for the What's New message icon.",
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"icon_alt": {
|
||||
"$ref": "file:///FxMSCommon.schema.json#/$defs/localizableText",
|
||||
"description": "Alt text for image."
|
||||
}
|
||||
},
|
||||
"additionalProperties": true,
|
||||
"required": ["published_date", "title", "body", "cta_url", "bucket_id"]
|
||||
},
|
||||
"template": {
|
||||
"type": "string",
|
||||
"const": "whatsnew_panel_message"
|
||||
}
|
||||
},
|
||||
"required": ["order"],
|
||||
"additionalProperties": true
|
||||
}
|
@ -122,7 +122,6 @@ const MESSAGE_TYPE_LIST = [
|
||||
"PBNEWTAB_MESSAGE_REQUEST",
|
||||
"DOORHANGER_TELEMETRY",
|
||||
"TOOLBAR_BADGE_TELEMETRY",
|
||||
"TOOLBAR_PANEL_TELEMETRY",
|
||||
"MOMENTS_PAGE_TELEMETRY",
|
||||
"INFOBAR_TELEMETRY",
|
||||
"SPOTLIGHT_TELEMETRY",
|
||||
@ -140,9 +139,7 @@ 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",
|
||||
|
@ -44,7 +44,6 @@ Please note that some targeting attributes require stricter controls on the tele
|
||||
* [isFxASignedIn](#isFxASignedIn)
|
||||
* [isMajorUpgrade](#ismajorupgrade)
|
||||
* [isRTAMO](#isrtamo)
|
||||
* [isWhatsNewPanelEnabled](#iswhatsnewpanelenabled)
|
||||
* [launchOnLoginEnabled](#launchonloginenabled)
|
||||
* [locale](#locale)
|
||||
* [localeLanguageCode](#localelanguagecode)
|
||||
@ -630,16 +629,6 @@ Boolean pref that gets set the first time the user opens the FxA toolbar panel
|
||||
declare const hasAccessedFxAPanel: boolean;
|
||||
```
|
||||
|
||||
### `isWhatsNewPanelEnabled`
|
||||
|
||||
Boolean pref that controls if the What's New panel feature is enabled
|
||||
|
||||
#### Definition
|
||||
|
||||
```ts
|
||||
declare const isWhatsNewPanelEnabled: boolean;
|
||||
```
|
||||
|
||||
### `totalBlockedCount`
|
||||
|
||||
Total number of events from the content blocking database
|
||||
|
@ -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, {
|
||||
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -72,12 +72,6 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
||||
"browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons",
|
||||
true
|
||||
);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"isWhatsNewPanelEnabled",
|
||||
"browser.messaging-system.whatsNewPanel.enabled",
|
||||
false
|
||||
);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"hasAccessedFxAPanel",
|
||||
@ -704,9 +698,6 @@ const TargetingGetters = {
|
||||
get hasAccessedFxAPanel() {
|
||||
return lazy.hasAccessedFxAPanel;
|
||||
},
|
||||
get isWhatsNewPanelEnabled() {
|
||||
return lazy.isWhatsNewPanelEnabled;
|
||||
},
|
||||
get userPrefs() {
|
||||
return {
|
||||
cfrFeatures: lazy.cfrFeaturesUserPref,
|
||||
|
@ -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",
|
||||
|
@ -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();
|
||||
|
@ -19,134 +19,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",
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
@ -38,7 +38,6 @@ EXTRA_JS_MODULES.asrouter += [
|
||||
"modules/Spotlight.sys.mjs",
|
||||
"modules/ToastNotification.sys.mjs",
|
||||
"modules/ToolbarBadgeHub.sys.mjs",
|
||||
"modules/ToolbarPanelHub.sys.mjs",
|
||||
]
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += [
|
||||
@ -57,7 +56,6 @@ TESTING_JS_MODULES += [
|
||||
"content-src/templates/OnboardingMessage/Spotlight.schema.json",
|
||||
"content-src/templates/OnboardingMessage/ToolbarBadgeMessage.schema.json",
|
||||
"content-src/templates/OnboardingMessage/UpdateAction.schema.json",
|
||||
"content-src/templates/OnboardingMessage/WhatsNewMessage.schema.json",
|
||||
"content-src/templates/PBNewtab/NewtabPromoMessage.schema.json",
|
||||
"content-src/templates/ToastNotification/ToastNotification.schema.json",
|
||||
"tests/InflightAssetsMessageProvider.sys.mjs",
|
||||
|
@ -14,11 +14,11 @@ const { ASRouter } = ChromeUtils.importESModule(
|
||||
const HOMEPAGE_OVERRIDE_PREF = "browser.startup.homepage_override.once";
|
||||
|
||||
add_task(async function test_with_rs_messages() {
|
||||
// Force the WNPanel provider cache to 0 by modifying updateCycleInMs
|
||||
// Force the cfr provider cache to 0 by modifying updateCycleInMs
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[
|
||||
"browser.newtabpage.activity-stream.asrouter.providers.whats-new-panel",
|
||||
"browser.newtabpage.activity-stream.asrouter.providers.cfr",
|
||||
`{"id":"cfr","enabled":true,"type":"remote-settings","collection":"cfr","updateCycleInMs":0}`,
|
||||
],
|
||||
],
|
||||
|
@ -48,7 +48,6 @@ describe("ASRouter", () => {
|
||||
let fakeAttributionCode;
|
||||
let fakeTargetingContext;
|
||||
let FakeToolbarBadgeHub;
|
||||
let FakeToolbarPanelHub;
|
||||
let FakeMomentsPageHub;
|
||||
let ASRouterTargeting;
|
||||
let screenImpressions;
|
||||
@ -151,7 +150,6 @@ describe("ASRouter", () => {
|
||||
cfr: "",
|
||||
"message-groups": "",
|
||||
"messaging-experiments": "",
|
||||
"whats-new-panel": "",
|
||||
},
|
||||
totalBookmarksCount: {},
|
||||
firefoxVersion: 80,
|
||||
@ -159,7 +157,6 @@ describe("ASRouter", () => {
|
||||
needsUpdate: {},
|
||||
hasPinnedTabs: false,
|
||||
hasAccessedFxAPanel: false,
|
||||
isWhatsNewPanelEnabled: true,
|
||||
userPrefs: {
|
||||
cfrFeatures: true,
|
||||
cfrAddons: true,
|
||||
@ -203,12 +200,6 @@ describe("ASRouter", () => {
|
||||
writeAttributionFile: () => Promise.resolve(),
|
||||
getCachedAttributionData: sinon.stub(),
|
||||
};
|
||||
FakeToolbarPanelHub = {
|
||||
init: sandbox.stub(),
|
||||
uninit: sandbox.stub(),
|
||||
forceShowMessage: sandbox.stub(),
|
||||
enableToolbarButton: sandbox.stub(),
|
||||
};
|
||||
FakeToolbarBadgeHub = {
|
||||
init: sandbox.stub(),
|
||||
uninit: sandbox.stub(),
|
||||
@ -252,7 +243,6 @@ describe("ASRouter", () => {
|
||||
PanelTestProvider,
|
||||
MacAttribution: { applicationPath: "" },
|
||||
ToolbarBadgeHub: FakeToolbarBadgeHub,
|
||||
ToolbarPanelHub: FakeToolbarPanelHub,
|
||||
MomentsPageHub: FakeMomentsPageHub,
|
||||
KintoHttpClient: class {
|
||||
bucket() {
|
||||
@ -354,7 +344,6 @@ describe("ASRouter", () => {
|
||||
// ASRouter init called in `beforeEach` block above
|
||||
|
||||
assert.calledOnce(FakeToolbarBadgeHub.init);
|
||||
assert.calledOnce(FakeToolbarPanelHub.init);
|
||||
assert.calledOnce(FakeMomentsPageHub.init);
|
||||
|
||||
assert.calledWithExactly(
|
||||
@ -369,15 +358,6 @@ describe("ASRouter", () => {
|
||||
}
|
||||
);
|
||||
|
||||
assert.calledWithExactly(
|
||||
FakeToolbarPanelHub.init,
|
||||
Router.waitForInitialized,
|
||||
{
|
||||
getMessages: Router.handleMessageRequest,
|
||||
sendTelemetry: Router.sendTelemetry,
|
||||
}
|
||||
);
|
||||
|
||||
assert.calledWithExactly(
|
||||
FakeMomentsPageHub.init,
|
||||
Router.waitForInitialized,
|
||||
@ -678,25 +658,10 @@ describe("ASRouter", () => {
|
||||
sandbox.stub(CFRPageActions, "addRecommendation");
|
||||
browser = {};
|
||||
});
|
||||
it("should route whatsnew_panel_message message to the right hub", () => {
|
||||
Router.routeCFRMessage(
|
||||
{ template: "whatsnew_panel_message" },
|
||||
browser,
|
||||
"",
|
||||
true
|
||||
);
|
||||
|
||||
assert.calledOnce(FakeToolbarPanelHub.forceShowMessage);
|
||||
assert.notCalled(FakeToolbarBadgeHub.registerBadgeNotificationListener);
|
||||
assert.notCalled(CFRPageActions.addRecommendation);
|
||||
assert.notCalled(CFRPageActions.forceRecommendation);
|
||||
assert.notCalled(FakeMomentsPageHub.executeAction);
|
||||
});
|
||||
it("should route moments messages to the right hub", () => {
|
||||
Router.routeCFRMessage({ template: "update_action" }, browser, "", true);
|
||||
|
||||
assert.calledOnce(FakeMomentsPageHub.executeAction);
|
||||
assert.notCalled(FakeToolbarPanelHub.forceShowMessage);
|
||||
assert.notCalled(FakeToolbarBadgeHub.registerBadgeNotificationListener);
|
||||
assert.notCalled(CFRPageActions.addRecommendation);
|
||||
assert.notCalled(CFRPageActions.forceRecommendation);
|
||||
@ -705,7 +670,6 @@ describe("ASRouter", () => {
|
||||
Router.routeCFRMessage({ template: "toolbar_badge" }, browser);
|
||||
|
||||
assert.calledOnce(FakeToolbarBadgeHub.registerBadgeNotificationListener);
|
||||
assert.notCalled(FakeToolbarPanelHub.forceShowMessage);
|
||||
assert.notCalled(CFRPageActions.addRecommendation);
|
||||
assert.notCalled(CFRPageActions.forceRecommendation);
|
||||
assert.notCalled(FakeMomentsPageHub.executeAction);
|
||||
@ -721,7 +685,6 @@ describe("ASRouter", () => {
|
||||
assert.calledOnce(CFRPageActions.addRecommendation);
|
||||
assert.notCalled(CFRPageActions.forceRecommendation);
|
||||
assert.notCalled(FakeToolbarBadgeHub.registerBadgeNotificationListener);
|
||||
assert.notCalled(FakeToolbarPanelHub.forceShowMessage);
|
||||
assert.notCalled(FakeMomentsPageHub.executeAction);
|
||||
});
|
||||
it("should route cfr_doorhanger message to the right hub force = false", () => {
|
||||
@ -733,7 +696,6 @@ describe("ASRouter", () => {
|
||||
);
|
||||
|
||||
assert.calledOnce(CFRPageActions.addRecommendation);
|
||||
assert.notCalled(FakeToolbarPanelHub.forceShowMessage);
|
||||
assert.notCalled(FakeToolbarBadgeHub.registerBadgeNotificationListener);
|
||||
assert.notCalled(CFRPageActions.forceRecommendation);
|
||||
assert.notCalled(FakeMomentsPageHub.executeAction);
|
||||
@ -742,7 +704,6 @@ describe("ASRouter", () => {
|
||||
Router.routeCFRMessage({ template: "cfr_doorhanger" }, browser, {}, true);
|
||||
|
||||
assert.calledOnce(CFRPageActions.forceRecommendation);
|
||||
assert.notCalled(FakeToolbarPanelHub.forceShowMessage);
|
||||
assert.notCalled(CFRPageActions.addRecommendation);
|
||||
assert.notCalled(FakeToolbarBadgeHub.registerBadgeNotificationListener);
|
||||
assert.notCalled(FakeMomentsPageHub.executeAction);
|
||||
@ -759,7 +720,6 @@ describe("ASRouter", () => {
|
||||
const { args } = CFRPageActions.addRecommendation.firstCall;
|
||||
// Host should be null
|
||||
assert.isNull(args[1]);
|
||||
assert.notCalled(FakeToolbarPanelHub.forceShowMessage);
|
||||
assert.notCalled(FakeToolbarBadgeHub.registerBadgeNotificationListener);
|
||||
assert.notCalled(CFRPageActions.forceRecommendation);
|
||||
assert.notCalled(FakeMomentsPageHub.executeAction);
|
||||
@ -773,7 +733,6 @@ describe("ASRouter", () => {
|
||||
);
|
||||
|
||||
assert.calledOnce(CFRPageActions.forceRecommendation);
|
||||
assert.notCalled(FakeToolbarPanelHub.forceShowMessage);
|
||||
assert.notCalled(CFRPageActions.addRecommendation);
|
||||
assert.notCalled(FakeToolbarBadgeHub.registerBadgeNotificationListener);
|
||||
assert.notCalled(FakeMomentsPageHub.executeAction);
|
||||
@ -786,7 +745,6 @@ describe("ASRouter", () => {
|
||||
true
|
||||
);
|
||||
|
||||
assert.notCalled(FakeToolbarPanelHub.forceShowMessage);
|
||||
assert.notCalled(CFRPageActions.forceRecommendation);
|
||||
assert.notCalled(CFRPageActions.addRecommendation);
|
||||
assert.notCalled(FakeToolbarBadgeHub.registerBadgeNotificationListener);
|
||||
@ -961,7 +919,6 @@ describe("ASRouter", () => {
|
||||
type: "local",
|
||||
enabled: true,
|
||||
messages: [
|
||||
"whatsnew_panel_message",
|
||||
"cfr_doorhanger",
|
||||
"toolbar_badge",
|
||||
"update_action",
|
||||
@ -1272,43 +1229,6 @@ describe("ASRouter", () => {
|
||||
Router.state.messageImpressions
|
||||
);
|
||||
});
|
||||
it("should return all unblocked messages that match the template, trigger if returnAll=true", async () => {
|
||||
const message1 = {
|
||||
provider: "whats_new",
|
||||
id: "1",
|
||||
template: "whatsnew_panel_message",
|
||||
trigger: { id: "whatsNewPanelOpened" },
|
||||
groups: ["whats_new"],
|
||||
};
|
||||
const message2 = {
|
||||
provider: "whats_new",
|
||||
id: "2",
|
||||
template: "whatsnew_panel_message",
|
||||
trigger: { id: "whatsNewPanelOpened" },
|
||||
groups: ["whats_new"],
|
||||
};
|
||||
const message3 = {
|
||||
provider: "whats_new",
|
||||
id: "3",
|
||||
template: "badge",
|
||||
groups: ["whats_new"],
|
||||
};
|
||||
ASRouterTargeting.findMatchingMessage.callsFake(() => [
|
||||
message2,
|
||||
message1,
|
||||
]);
|
||||
await Router.setState({
|
||||
messages: [message3, message2, message1],
|
||||
providers: [{ id: "whats_new" }],
|
||||
});
|
||||
const result = await Router.handleMessageRequest({
|
||||
template: "whatsnew_panel_message",
|
||||
triggerId: "whatsNewPanelOpened",
|
||||
returnAll: true,
|
||||
});
|
||||
|
||||
assert.deepEqual(result, [message2, message1]);
|
||||
});
|
||||
it("should forward trigger param info", async () => {
|
||||
const trigger = {
|
||||
triggerId: "foo",
|
||||
@ -1854,33 +1774,6 @@ describe("ASRouter", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#forceWNPanel", () => {
|
||||
let browser = {
|
||||
ownerGlobal: {
|
||||
document: new Document(),
|
||||
PanelUI: {
|
||||
showSubView: sinon.stub(),
|
||||
panel: {
|
||||
setAttribute: sinon.stub(),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
let fakePanel = {
|
||||
setAttribute: sinon.stub(),
|
||||
};
|
||||
sinon
|
||||
.stub(browser.ownerGlobal.document, "getElementById")
|
||||
.returns(fakePanel);
|
||||
|
||||
it("should call enableToolbarButton", async () => {
|
||||
await Router.forceWNPanel(browser);
|
||||
assert.calledOnce(FakeToolbarPanelHub.enableToolbarButton);
|
||||
assert.calledOnce(browser.ownerGlobal.PanelUI.showSubView);
|
||||
assert.calledWith(fakePanel.setAttribute, "noautohide", true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_triggerHandler", () => {
|
||||
it("should call #sendTriggerMessage with the correct trigger", () => {
|
||||
const getter = sandbox.stub();
|
||||
|
@ -24,7 +24,6 @@ describe("ASRouterChild", () => {
|
||||
msg.DISABLE_PROVIDER,
|
||||
msg.ENABLE_PROVIDER,
|
||||
msg.EXPIRE_QUERY_CACHE,
|
||||
msg.FORCE_WHATSNEW_PANEL,
|
||||
msg.IMPRESSION,
|
||||
msg.RESET_PROVIDER_PREF,
|
||||
msg.SET_PROVIDER_USER_PREF,
|
||||
|
@ -14,8 +14,6 @@ describe("ASRouterParentProcessMessageHandler", () => {
|
||||
"addImpression",
|
||||
"evaluateExpression",
|
||||
"forceAttribution",
|
||||
"forceWNPanel",
|
||||
"closeWNPanel",
|
||||
"forcePBWindow",
|
||||
"resetGroupsState",
|
||||
"resetMessageState",
|
||||
@ -122,7 +120,6 @@ describe("ASRouterParentProcessMessageHandler", () => {
|
||||
[
|
||||
msg.AS_ROUTER_TELEMETRY_USER_EVENT,
|
||||
msg.TOOLBAR_BADGE_TELEMETRY,
|
||||
msg.TOOLBAR_PANEL_TELEMETRY,
|
||||
msg.MOMENTS_PAGE_TELEMETRY,
|
||||
msg.DOORHANGER_TELEMETRY,
|
||||
].forEach(type => {
|
||||
@ -309,28 +306,6 @@ describe("ASRouterParentProcessMessageHandler", () => {
|
||||
assert.calledOnce(config.router.forceAttribution);
|
||||
});
|
||||
});
|
||||
describe("FORCE_WHATSNEW_PANEL action", () => {
|
||||
it("default calls forceWNPanel", () => {
|
||||
handler.handleMessage(
|
||||
msg.FORCE_WHATSNEW_PANEL,
|
||||
{},
|
||||
{ browser: { ownerGlobal: {} } }
|
||||
);
|
||||
assert.calledOnce(config.router.forceWNPanel);
|
||||
assert.calledWith(config.router.forceWNPanel, { ownerGlobal: {} });
|
||||
});
|
||||
});
|
||||
describe("CLOSE_WHATSNEW_PANEL action", () => {
|
||||
it("default calls closeWNPanel", () => {
|
||||
handler.handleMessage(
|
||||
msg.CLOSE_WHATSNEW_PANEL,
|
||||
{},
|
||||
{ browser: { ownerGlobal: {} } }
|
||||
);
|
||||
assert.calledOnce(config.router.closeWNPanel);
|
||||
assert.calledWith(config.router.closeWNPanel, { ownerGlobal: {} });
|
||||
});
|
||||
});
|
||||
describe("FORCE_PRIVATE_BROWSING_WINDOW action", () => {
|
||||
it("default calls forcePBWindow", () => {
|
||||
handler.handleMessage(
|
||||
|
@ -1,10 +1,6 @@
|
||||
import { _ToolbarBadgeHub } from "modules/ToolbarBadgeHub.sys.mjs";
|
||||
import { GlobalOverrider } from "test/unit/utils";
|
||||
import { OnboardingMessageProvider } from "modules/OnboardingMessageProvider.sys.mjs";
|
||||
import {
|
||||
_ToolbarPanelHub,
|
||||
ToolbarPanelHub,
|
||||
} from "modules/ToolbarPanelHub.sys.mjs";
|
||||
|
||||
describe("ToolbarBadgeHub", () => {
|
||||
let sandbox;
|
||||
@ -13,7 +9,6 @@ describe("ToolbarBadgeHub", () => {
|
||||
let fakeSendTelemetry;
|
||||
let isBrowserPrivateStub;
|
||||
let fxaMessage;
|
||||
let whatsnewMessage;
|
||||
let fakeElement;
|
||||
let globals;
|
||||
let everyWindowStub;
|
||||
@ -36,28 +31,6 @@ describe("ToolbarBadgeHub", () => {
|
||||
const onboardingMsgs =
|
||||
await OnboardingMessageProvider.getUntranslatedMessages();
|
||||
fxaMessage = onboardingMsgs.find(({ id }) => id === "FXA_ACCOUNTS_BADGE");
|
||||
whatsnewMessage = {
|
||||
id: `WHATS_NEW_BADGE_71`,
|
||||
template: "toolbar_badge",
|
||||
content: {
|
||||
delay: 1000,
|
||||
target: "whats-new-menu-button",
|
||||
action: { id: "show-whatsnew-button" },
|
||||
badgeDescription: { string_id: "cfr-badge-reader-label-newfeature" },
|
||||
},
|
||||
priority: 1,
|
||||
trigger: { id: "toolbarBadgeUpdate" },
|
||||
frequency: {
|
||||
// Makes it so that we track impressions for this message while at the
|
||||
// same time it can have unlimited impressions
|
||||
lifetime: Infinity,
|
||||
},
|
||||
// Never saw this message or saw it in the past 4 days or more recent
|
||||
targeting: `isWhatsNewPanelEnabled &&
|
||||
(!messageImpressions['WHATS_NEW_BADGE_71'] ||
|
||||
(messageImpressions['WHATS_NEW_BADGE_71']|length >= 1 &&
|
||||
currentDate|date - messageImpressions['WHATS_NEW_BADGE_71'][0] <= 4 * 24 * 3600 * 1000))`,
|
||||
};
|
||||
fakeElement = {
|
||||
classList: {
|
||||
add: sandbox.stub(),
|
||||
@ -93,7 +66,6 @@ describe("ToolbarBadgeHub", () => {
|
||||
setStringPrefStub = sandbox.stub();
|
||||
requestIdleCallbackStub = sandbox.stub().callsFake(fn => fn());
|
||||
globals.set({
|
||||
ToolbarPanelHub,
|
||||
requestIdleCallback: requestIdleCallbackStub,
|
||||
EveryWindow: everyWindowStub,
|
||||
PrivateBrowsingUtils: { isBrowserPrivate: isBrowserPrivateStub },
|
||||
@ -139,16 +111,6 @@ describe("ToolbarBadgeHub", () => {
|
||||
|
||||
assert.calledTwice(instance.messageRequest);
|
||||
});
|
||||
it("should add a pref observer", async () => {
|
||||
await instance.init(sandbox.stub().resolves(), {});
|
||||
|
||||
assert.calledOnce(addObserverStub);
|
||||
assert.calledWithExactly(
|
||||
addObserverStub,
|
||||
instance.prefs.WHATSNEW_TOOLBAR_PANEL,
|
||||
instance
|
||||
);
|
||||
});
|
||||
});
|
||||
describe("#uninit", () => {
|
||||
beforeEach(async () => {
|
||||
@ -164,16 +126,6 @@ describe("ToolbarBadgeHub", () => {
|
||||
assert.calledOnce(clearTimeoutStub);
|
||||
assert.calledWithExactly(clearTimeoutStub, 2);
|
||||
});
|
||||
it("should remove the pref observer", () => {
|
||||
instance.uninit();
|
||||
|
||||
assert.calledOnce(removeObserverStub);
|
||||
assert.calledWithExactly(
|
||||
removeObserverStub,
|
||||
instance.prefs.WHATSNEW_TOOLBAR_PANEL,
|
||||
instance
|
||||
);
|
||||
});
|
||||
});
|
||||
describe("messageRequest", () => {
|
||||
let handleMessageRequestStub;
|
||||
@ -293,66 +245,6 @@ describe("ToolbarBadgeHub", () => {
|
||||
instance.removeAllNotifications
|
||||
);
|
||||
});
|
||||
it("should execute actions if they exist", () => {
|
||||
sandbox.stub(instance, "executeAction");
|
||||
instance.addToolbarNotification(target, whatsnewMessage);
|
||||
|
||||
assert.calledOnce(instance.executeAction);
|
||||
assert.calledWithExactly(instance.executeAction, {
|
||||
...whatsnewMessage.content.action,
|
||||
message_id: whatsnewMessage.id,
|
||||
});
|
||||
});
|
||||
it("should create a description element", () => {
|
||||
sandbox.stub(instance, "executeAction");
|
||||
instance.addToolbarNotification(target, whatsnewMessage);
|
||||
|
||||
assert.calledOnce(fakeDocument.createElement);
|
||||
assert.calledWithExactly(fakeDocument.createElement, "span");
|
||||
});
|
||||
it("should set description id to element and to button", () => {
|
||||
sandbox.stub(instance, "executeAction");
|
||||
instance.addToolbarNotification(target, whatsnewMessage);
|
||||
|
||||
assert.calledWithExactly(
|
||||
fakeElement.setAttribute,
|
||||
"id",
|
||||
"toolbarbutton-notification-description"
|
||||
);
|
||||
assert.calledWithExactly(
|
||||
fakeElement.setAttribute,
|
||||
"aria-labelledby",
|
||||
`toolbarbutton-notification-description ${whatsnewMessage.content.target}`
|
||||
);
|
||||
});
|
||||
it("should attach fluent id to description", () => {
|
||||
sandbox.stub(instance, "executeAction");
|
||||
instance.addToolbarNotification(target, whatsnewMessage);
|
||||
|
||||
assert.calledOnce(fakeDocument.l10n.setAttributes);
|
||||
assert.calledWithExactly(
|
||||
fakeDocument.l10n.setAttributes,
|
||||
fakeElement,
|
||||
whatsnewMessage.content.badgeDescription.string_id
|
||||
);
|
||||
});
|
||||
it("should add an impression for the message", () => {
|
||||
instance.addToolbarNotification(target, whatsnewMessage);
|
||||
|
||||
assert.calledOnce(instance._addImpression);
|
||||
assert.calledWithExactly(instance._addImpression, whatsnewMessage);
|
||||
});
|
||||
it("should send an impression ping", async () => {
|
||||
sandbox.stub(instance, "sendUserEventTelemetry");
|
||||
instance.addToolbarNotification(target, whatsnewMessage);
|
||||
|
||||
assert.calledOnce(instance.sendUserEventTelemetry);
|
||||
assert.calledWithExactly(
|
||||
instance.sendUserEventTelemetry,
|
||||
"IMPRESSION",
|
||||
whatsnewMessage
|
||||
);
|
||||
});
|
||||
});
|
||||
describe("registerBadgeNotificationListener", () => {
|
||||
let msg_no_delay;
|
||||
@ -410,44 +302,6 @@ describe("ToolbarBadgeHub", () => {
|
||||
assert.calledOnce(everyWindowStub.unregisterCallback);
|
||||
assert.calledWithExactly(everyWindowStub.unregisterCallback, instance.id);
|
||||
});
|
||||
it("should only call executeAction for 'update_action' messages", () => {
|
||||
const stub = sandbox.stub(instance, "executeAction");
|
||||
const updateActionMsg = { ...msg_no_delay, template: "update_action" };
|
||||
|
||||
instance.registerBadgeNotificationListener(updateActionMsg);
|
||||
|
||||
assert.notCalled(everyWindowStub.registerCallback);
|
||||
assert.calledOnce(stub);
|
||||
});
|
||||
});
|
||||
describe("executeAction", () => {
|
||||
let blockMessageByIdStub;
|
||||
beforeEach(async () => {
|
||||
blockMessageByIdStub = sandbox.stub();
|
||||
await instance.init(sandbox.stub().resolves(), {
|
||||
blockMessageById: blockMessageByIdStub,
|
||||
});
|
||||
});
|
||||
it("should call ToolbarPanelHub.enableToolbarButton", () => {
|
||||
const stub = sandbox.stub(
|
||||
_ToolbarPanelHub.prototype,
|
||||
"enableToolbarButton"
|
||||
);
|
||||
|
||||
instance.executeAction({ id: "show-whatsnew-button" });
|
||||
|
||||
assert.calledOnce(stub);
|
||||
});
|
||||
it("should call ToolbarPanelHub.enableAppmenuButton", () => {
|
||||
const stub = sandbox.stub(
|
||||
_ToolbarPanelHub.prototype,
|
||||
"enableAppmenuButton"
|
||||
);
|
||||
|
||||
instance.executeAction({ id: "show-whatsnew-button" });
|
||||
|
||||
assert.calledOnce(stub);
|
||||
});
|
||||
});
|
||||
describe("removeToolbarNotification", () => {
|
||||
it("should remove the notification", () => {
|
||||
@ -629,24 +483,4 @@ describe("ToolbarBadgeHub", () => {
|
||||
assert.propertyVal(ping.data, "event", "CLICK");
|
||||
});
|
||||
});
|
||||
describe("#observe", () => {
|
||||
it("should make a message request when the whats new pref is changed", () => {
|
||||
sandbox.stub(instance, "messageRequest");
|
||||
|
||||
instance.observe("", "", instance.prefs.WHATSNEW_TOOLBAR_PANEL);
|
||||
|
||||
assert.calledOnce(instance.messageRequest);
|
||||
assert.calledWithExactly(instance.messageRequest, {
|
||||
template: "toolbar_badge",
|
||||
triggerId: "toolbarBadgeUpdate",
|
||||
});
|
||||
});
|
||||
it("should not react to other pref changes", () => {
|
||||
sandbox.stub(instance, "messageRequest");
|
||||
|
||||
instance.observe("", "", "foo");
|
||||
|
||||
assert.notCalled(instance.messageRequest);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,760 +0,0 @@
|
||||
import { _ToolbarPanelHub } from "modules/ToolbarPanelHub.sys.mjs";
|
||||
import { GlobalOverrider } from "test/unit/utils";
|
||||
import { PanelTestProvider } from "modules/PanelTestProvider.sys.mjs";
|
||||
|
||||
describe("ToolbarPanelHub", () => {
|
||||
let globals;
|
||||
let sandbox;
|
||||
let instance;
|
||||
let everyWindowStub;
|
||||
let fakeDocument;
|
||||
let fakeWindow;
|
||||
let fakeElementById;
|
||||
let fakeElementByTagName;
|
||||
let createdCustomElements = [];
|
||||
let eventListeners = {};
|
||||
let addObserverStub;
|
||||
let removeObserverStub;
|
||||
let getBoolPrefStub;
|
||||
let setBoolPrefStub;
|
||||
let waitForInitializedStub;
|
||||
let isBrowserPrivateStub;
|
||||
let fakeSendTelemetry;
|
||||
let getEarliestRecordedDateStub;
|
||||
let getEventsByDateRangeStub;
|
||||
let defaultSearchStub;
|
||||
let scriptloaderStub;
|
||||
let fakeRemoteL10n;
|
||||
let getViewNodeStub;
|
||||
|
||||
beforeEach(async () => {
|
||||
sandbox = sinon.createSandbox();
|
||||
globals = new GlobalOverrider();
|
||||
instance = new _ToolbarPanelHub();
|
||||
waitForInitializedStub = sandbox.stub().resolves();
|
||||
fakeElementById = {
|
||||
setAttribute: sandbox.stub(),
|
||||
removeAttribute: sandbox.stub(),
|
||||
querySelector: sandbox.stub().returns(null),
|
||||
querySelectorAll: sandbox.stub().returns([]),
|
||||
appendChild: sandbox.stub(),
|
||||
addEventListener: sandbox.stub(),
|
||||
hasAttribute: sandbox.stub(),
|
||||
toggleAttribute: sandbox.stub(),
|
||||
remove: sandbox.stub(),
|
||||
removeChild: sandbox.stub(),
|
||||
};
|
||||
fakeElementByTagName = {
|
||||
setAttribute: sandbox.stub(),
|
||||
removeAttribute: sandbox.stub(),
|
||||
querySelector: sandbox.stub().returns(null),
|
||||
querySelectorAll: sandbox.stub().returns([]),
|
||||
appendChild: sandbox.stub(),
|
||||
addEventListener: sandbox.stub(),
|
||||
hasAttribute: sandbox.stub(),
|
||||
toggleAttribute: sandbox.stub(),
|
||||
remove: sandbox.stub(),
|
||||
removeChild: sandbox.stub(),
|
||||
};
|
||||
fakeDocument = {
|
||||
getElementById: sandbox.stub().returns(fakeElementById),
|
||||
getElementsByTagName: sandbox.stub().returns(fakeElementByTagName),
|
||||
querySelector: sandbox.stub().returns({}),
|
||||
createElement: tagName => {
|
||||
const element = {
|
||||
tagName,
|
||||
classList: {},
|
||||
addEventListener: (ev, fn) => {
|
||||
eventListeners[ev] = fn;
|
||||
},
|
||||
appendChild: sandbox.stub(),
|
||||
setAttribute: sandbox.stub(),
|
||||
textContent: "",
|
||||
};
|
||||
element.classList.add = sandbox.stub();
|
||||
element.classList.includes = className =>
|
||||
element.classList.add.firstCall.args[0] === className;
|
||||
createdCustomElements.push(element);
|
||||
return element;
|
||||
},
|
||||
l10n: {
|
||||
translateElements: sandbox.stub(),
|
||||
translateFragment: sandbox.stub(),
|
||||
formatMessages: sandbox.stub().resolves([{}]),
|
||||
setAttributes: sandbox.stub(),
|
||||
},
|
||||
};
|
||||
fakeWindow = {
|
||||
// eslint-disable-next-line object-shorthand
|
||||
DocumentFragment: function () {
|
||||
return fakeElementById;
|
||||
},
|
||||
document: fakeDocument,
|
||||
browser: {
|
||||
ownerDocument: fakeDocument,
|
||||
},
|
||||
MozXULElement: { insertFTLIfNeeded: sandbox.stub() },
|
||||
ownerGlobal: {
|
||||
openLinkIn: sandbox.stub(),
|
||||
gBrowser: "gBrowser",
|
||||
},
|
||||
PanelUI: {
|
||||
panel: fakeElementById,
|
||||
whatsNewPanel: fakeElementById,
|
||||
},
|
||||
customElements: { get: sandbox.stub() },
|
||||
};
|
||||
everyWindowStub = {
|
||||
registerCallback: sandbox.stub(),
|
||||
unregisterCallback: sandbox.stub(),
|
||||
};
|
||||
scriptloaderStub = { loadSubScript: sandbox.stub() };
|
||||
addObserverStub = sandbox.stub();
|
||||
removeObserverStub = sandbox.stub();
|
||||
getBoolPrefStub = sandbox.stub();
|
||||
setBoolPrefStub = sandbox.stub();
|
||||
fakeSendTelemetry = sandbox.stub();
|
||||
isBrowserPrivateStub = sandbox.stub();
|
||||
getEarliestRecordedDateStub = sandbox.stub().returns(
|
||||
// A random date that's not the current timestamp
|
||||
new Date() - 500
|
||||
);
|
||||
getEventsByDateRangeStub = sandbox.stub().returns([]);
|
||||
getViewNodeStub = sandbox.stub().returns(fakeElementById);
|
||||
defaultSearchStub = { defaultEngine: { name: "DDG" } };
|
||||
fakeRemoteL10n = {
|
||||
l10n: {},
|
||||
reloadL10n: sandbox.stub(),
|
||||
createElement: sandbox
|
||||
.stub()
|
||||
.callsFake((doc, el) => fakeDocument.createElement(el)),
|
||||
};
|
||||
globals.set({
|
||||
EveryWindow: everyWindowStub,
|
||||
Services: {
|
||||
...Services,
|
||||
prefs: {
|
||||
addObserver: addObserverStub,
|
||||
removeObserver: removeObserverStub,
|
||||
getBoolPref: getBoolPrefStub,
|
||||
setBoolPref: setBoolPrefStub,
|
||||
},
|
||||
search: defaultSearchStub,
|
||||
scriptloader: scriptloaderStub,
|
||||
},
|
||||
PrivateBrowsingUtils: {
|
||||
isBrowserPrivate: isBrowserPrivateStub,
|
||||
},
|
||||
TrackingDBService: {
|
||||
getEarliestRecordedDate: getEarliestRecordedDateStub,
|
||||
getEventsByDateRange: getEventsByDateRangeStub,
|
||||
},
|
||||
SpecialMessageActions: {
|
||||
handleAction: sandbox.stub(),
|
||||
},
|
||||
RemoteL10n: fakeRemoteL10n,
|
||||
PanelMultiView: {
|
||||
getViewNode: getViewNodeStub,
|
||||
},
|
||||
});
|
||||
});
|
||||
afterEach(() => {
|
||||
instance.uninit();
|
||||
sandbox.restore();
|
||||
globals.restore();
|
||||
eventListeners = {};
|
||||
createdCustomElements = [];
|
||||
});
|
||||
it("should create an instance", () => {
|
||||
assert.ok(instance);
|
||||
});
|
||||
it("should enableAppmenuButton() on init() just once", async () => {
|
||||
instance.enableAppmenuButton = sandbox.stub();
|
||||
|
||||
await instance.init(waitForInitializedStub, { getMessages: () => {} });
|
||||
await instance.init(waitForInitializedStub, { getMessages: () => {} });
|
||||
|
||||
assert.calledOnce(instance.enableAppmenuButton);
|
||||
|
||||
instance.uninit();
|
||||
|
||||
await instance.init(waitForInitializedStub, { getMessages: () => {} });
|
||||
|
||||
assert.calledTwice(instance.enableAppmenuButton);
|
||||
});
|
||||
it("should unregisterCallback on uninit()", () => {
|
||||
instance.uninit();
|
||||
assert.calledTwice(everyWindowStub.unregisterCallback);
|
||||
});
|
||||
describe("#maybeLoadCustomElement", () => {
|
||||
it("should not load customElements a second time", () => {
|
||||
instance.maybeLoadCustomElement({ customElements: new Map() });
|
||||
instance.maybeLoadCustomElement({
|
||||
customElements: new Map([["remote-text", true]]),
|
||||
});
|
||||
|
||||
assert.calledOnce(scriptloaderStub.loadSubScript);
|
||||
});
|
||||
});
|
||||
describe("#toggleWhatsNewPref", () => {
|
||||
it("should call Services.prefs.setBoolPref() with the opposite value", () => {
|
||||
let checkbox = {};
|
||||
let event = { target: checkbox };
|
||||
// checkbox starts false
|
||||
checkbox.checked = false;
|
||||
|
||||
// toggling the checkbox to set the value to true;
|
||||
// Preferences.set() gets called before the checkbox changes,
|
||||
// so we have to call it with the opposite value.
|
||||
instance.toggleWhatsNewPref(event);
|
||||
|
||||
assert.calledOnce(setBoolPrefStub);
|
||||
assert.calledWith(
|
||||
setBoolPrefStub,
|
||||
"browser.messaging-system.whatsNewPanel.enabled",
|
||||
!checkbox.checked
|
||||
);
|
||||
});
|
||||
it("should report telemetry with the opposite value", () => {
|
||||
let sendUserEventTelemetryStub = sandbox.stub(
|
||||
instance,
|
||||
"sendUserEventTelemetry"
|
||||
);
|
||||
let event = {
|
||||
target: { checked: true, ownerGlobal: fakeWindow },
|
||||
};
|
||||
|
||||
instance.toggleWhatsNewPref(event);
|
||||
|
||||
assert.calledOnce(sendUserEventTelemetryStub);
|
||||
const { args } = sendUserEventTelemetryStub.firstCall;
|
||||
assert.equal(args[1], "WNP_PREF_TOGGLE");
|
||||
assert.propertyVal(args[3].value, "prefValue", false);
|
||||
});
|
||||
});
|
||||
describe("#enableAppmenuButton", () => {
|
||||
it("should registerCallback on enableAppmenuButton() if there are messages", async () => {
|
||||
await instance.init(waitForInitializedStub, {
|
||||
getMessages: sandbox.stub().resolves([{}, {}]),
|
||||
});
|
||||
// init calls `enableAppmenuButton`
|
||||
everyWindowStub.registerCallback.resetHistory();
|
||||
|
||||
await instance.enableAppmenuButton();
|
||||
|
||||
assert.calledOnce(everyWindowStub.registerCallback);
|
||||
assert.calledWithExactly(
|
||||
everyWindowStub.registerCallback,
|
||||
"appMenu-whatsnew-button",
|
||||
sinon.match.func,
|
||||
sinon.match.func
|
||||
);
|
||||
});
|
||||
it("should not registerCallback on enableAppmenuButton() if there are no messages", async () => {
|
||||
instance.init(waitForInitializedStub, {
|
||||
getMessages: sandbox.stub().resolves([]),
|
||||
});
|
||||
// init calls `enableAppmenuButton`
|
||||
everyWindowStub.registerCallback.resetHistory();
|
||||
|
||||
await instance.enableAppmenuButton();
|
||||
|
||||
assert.notCalled(everyWindowStub.registerCallback);
|
||||
});
|
||||
});
|
||||
describe("#disableAppmenuButton", () => {
|
||||
it("should call the unregisterCallback", () => {
|
||||
assert.notCalled(everyWindowStub.unregisterCallback);
|
||||
|
||||
instance.disableAppmenuButton();
|
||||
|
||||
assert.calledOnce(everyWindowStub.unregisterCallback);
|
||||
assert.calledWithExactly(
|
||||
everyWindowStub.unregisterCallback,
|
||||
"appMenu-whatsnew-button"
|
||||
);
|
||||
});
|
||||
});
|
||||
describe("#enableToolbarButton", () => {
|
||||
it("should registerCallback on enableToolbarButton if messages.length", async () => {
|
||||
await instance.init(waitForInitializedStub, {
|
||||
getMessages: sandbox.stub().resolves([{}, {}]),
|
||||
});
|
||||
// init calls `enableAppmenuButton`
|
||||
everyWindowStub.registerCallback.resetHistory();
|
||||
|
||||
await instance.enableToolbarButton();
|
||||
|
||||
assert.calledOnce(everyWindowStub.registerCallback);
|
||||
assert.calledWithExactly(
|
||||
everyWindowStub.registerCallback,
|
||||
"whats-new-menu-button",
|
||||
sinon.match.func,
|
||||
sinon.match.func
|
||||
);
|
||||
});
|
||||
it("should not registerCallback on enableToolbarButton if no messages", async () => {
|
||||
await instance.init(waitForInitializedStub, {
|
||||
getMessages: sandbox.stub().resolves([]),
|
||||
});
|
||||
|
||||
await instance.enableToolbarButton();
|
||||
|
||||
assert.notCalled(everyWindowStub.registerCallback);
|
||||
});
|
||||
});
|
||||
describe("Show/Hide functions", () => {
|
||||
it("should unhide appmenu button on _showAppmenuButton()", async () => {
|
||||
await instance._showAppmenuButton(fakeWindow);
|
||||
|
||||
assert.equal(fakeElementById.hidden, false);
|
||||
});
|
||||
it("should hide appmenu button on _hideAppmenuButton()", () => {
|
||||
instance._hideAppmenuButton(fakeWindow);
|
||||
assert.equal(fakeElementById.hidden, true);
|
||||
});
|
||||
it("should not do anything if the window is closed", () => {
|
||||
instance._hideAppmenuButton(fakeWindow, true);
|
||||
assert.notCalled(global.PanelMultiView.getViewNode);
|
||||
});
|
||||
it("should not throw if the element does not exist", () => {
|
||||
let fn = instance._hideAppmenuButton.bind(null, {
|
||||
browser: { ownerDocument: {} },
|
||||
});
|
||||
getViewNodeStub.returns(undefined);
|
||||
assert.doesNotThrow(fn);
|
||||
});
|
||||
it("should unhide toolbar button on _showToolbarButton()", async () => {
|
||||
await instance._showToolbarButton(fakeWindow);
|
||||
|
||||
assert.equal(fakeElementById.hidden, false);
|
||||
});
|
||||
it("should hide toolbar button on _hideToolbarButton()", () => {
|
||||
instance._hideToolbarButton(fakeWindow);
|
||||
assert.equal(fakeElementById.hidden, true);
|
||||
});
|
||||
});
|
||||
describe("#renderMessages", () => {
|
||||
let getMessagesStub;
|
||||
beforeEach(() => {
|
||||
getMessagesStub = sandbox.stub();
|
||||
instance.init(waitForInitializedStub, {
|
||||
getMessages: getMessagesStub,
|
||||
sendTelemetry: fakeSendTelemetry,
|
||||
});
|
||||
});
|
||||
it("should have correct state", async () => {
|
||||
const messages = (await PanelTestProvider.getMessages()).filter(
|
||||
m => m.template === "whatsnew_panel_message"
|
||||
);
|
||||
|
||||
getMessagesStub.returns(messages);
|
||||
const ev1 = sandbox.stub();
|
||||
ev1.withArgs("type").returns(1); // tracker
|
||||
ev1.withArgs("count").returns(4);
|
||||
const ev2 = sandbox.stub();
|
||||
ev2.withArgs("type").returns(4); // fingerprinter
|
||||
ev2.withArgs("count").returns(3);
|
||||
getEventsByDateRangeStub.returns([
|
||||
{ getResultByName: ev1 },
|
||||
{ getResultByName: ev2 },
|
||||
]);
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
assert.propertyVal(instance.state.contentArguments, "trackerCount", 4);
|
||||
assert.propertyVal(
|
||||
instance.state.contentArguments,
|
||||
"fingerprinterCount",
|
||||
3
|
||||
);
|
||||
});
|
||||
it("should render messages to the panel on renderMessages()", async () => {
|
||||
const messages = (await PanelTestProvider.getMessages()).filter(
|
||||
m => m.template === "whatsnew_panel_message"
|
||||
);
|
||||
messages[0].content.link_text = { string_id: "link_text_id" };
|
||||
|
||||
getMessagesStub.returns(messages);
|
||||
const ev1 = sandbox.stub();
|
||||
ev1.withArgs("type").returns(1); // tracker
|
||||
ev1.withArgs("count").returns(4);
|
||||
const ev2 = sandbox.stub();
|
||||
ev2.withArgs("type").returns(4); // fingerprinter
|
||||
ev2.withArgs("count").returns(3);
|
||||
getEventsByDateRangeStub.returns([
|
||||
{ getResultByName: ev1 },
|
||||
{ getResultByName: ev2 },
|
||||
]);
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
for (let message of messages) {
|
||||
assert.ok(
|
||||
fakeRemoteL10n.createElement.args.find(
|
||||
([, , args]) => args && args.classList === "whatsNew-message-title"
|
||||
)
|
||||
);
|
||||
if (message.content.layout === "tracking-protections") {
|
||||
assert.ok(
|
||||
fakeRemoteL10n.createElement.args.find(
|
||||
([, , args]) =>
|
||||
args && args.classList === "whatsNew-message-subtitle"
|
||||
)
|
||||
);
|
||||
}
|
||||
if (message.id === "WHATS_NEW_FINGERPRINTER_COUNTER_72") {
|
||||
assert.ok(
|
||||
fakeRemoteL10n.createElement.args.find(
|
||||
([, el, args]) => el === "h2" && args.content === 3
|
||||
)
|
||||
);
|
||||
}
|
||||
assert.ok(
|
||||
fakeRemoteL10n.createElement.args.find(
|
||||
([, , args]) =>
|
||||
args && args.classList === "whatsNew-message-content"
|
||||
)
|
||||
);
|
||||
}
|
||||
// Call the click handler to make coverage happy.
|
||||
eventListeners.mouseup();
|
||||
assert.calledOnce(global.SpecialMessageActions.handleAction);
|
||||
});
|
||||
it("should clear previous messages on 2nd renderMessages()", async () => {
|
||||
const messages = (await PanelTestProvider.getMessages()).filter(
|
||||
m => m.template === "whatsnew_panel_message"
|
||||
);
|
||||
const removeStub = sandbox.stub();
|
||||
fakeElementById.querySelectorAll.onCall(0).returns([]);
|
||||
fakeElementById.querySelectorAll
|
||||
.onCall(1)
|
||||
.returns([{ remove: removeStub }, { remove: removeStub }]);
|
||||
|
||||
getMessagesStub.returns(messages);
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
assert.calledTwice(removeStub);
|
||||
});
|
||||
it("should sort based on order field value", async () => {
|
||||
const messages = (await PanelTestProvider.getMessages()).filter(
|
||||
m =>
|
||||
m.template === "whatsnew_panel_message" &&
|
||||
m.content.published_date === 1560969794394
|
||||
);
|
||||
|
||||
messages.forEach(m => (m.content.title = m.order));
|
||||
|
||||
getMessagesStub.returns(messages);
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
// Select the title elements that are supposed to be set to the same
|
||||
// value as the `order` field of the message
|
||||
const titleEls = fakeRemoteL10n.createElement.args
|
||||
.filter(
|
||||
([, , args]) => args && args.classList === "whatsNew-message-title"
|
||||
)
|
||||
.map(([, , args]) => args.content);
|
||||
assert.deepEqual(titleEls, [1, 2, 3]);
|
||||
});
|
||||
it("should accept string for image attributes", async () => {
|
||||
const messages = (await PanelTestProvider.getMessages()).filter(
|
||||
m => m.id === "WHATS_NEW_70_1"
|
||||
);
|
||||
getMessagesStub.returns(messages);
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
const imageEl = createdCustomElements.find(el => el.tagName === "img");
|
||||
assert.calledOnce(imageEl.setAttribute);
|
||||
assert.calledWithExactly(
|
||||
imageEl.setAttribute,
|
||||
"alt",
|
||||
"Firefox Send Logo"
|
||||
);
|
||||
});
|
||||
it("should set state values as data-attribute", async () => {
|
||||
const message = (await PanelTestProvider.getMessages()).find(
|
||||
m => m.template === "whatsnew_panel_message"
|
||||
);
|
||||
getMessagesStub.returns([message]);
|
||||
instance.state.contentArguments = { foo: "foo", bar: "bar" };
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
const [, , args] = fakeRemoteL10n.createElement.args.find(
|
||||
([, , elArgs]) => elArgs && elArgs.attributes
|
||||
);
|
||||
assert.ok(args);
|
||||
// Currently this.state.contentArguments has 8 different entries
|
||||
assert.lengthOf(Object.keys(args.attributes), 8);
|
||||
assert.equal(
|
||||
args.attributes.searchEngineName,
|
||||
defaultSearchStub.defaultEngine.name
|
||||
);
|
||||
});
|
||||
it("should only render unique dates (no duplicates)", async () => {
|
||||
const messages = (await PanelTestProvider.getMessages()).filter(
|
||||
m => m.template === "whatsnew_panel_message"
|
||||
);
|
||||
const uniqueDates = [
|
||||
...new Set(messages.map(m => m.content.published_date)),
|
||||
];
|
||||
getMessagesStub.returns(messages);
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
const dateElements = fakeRemoteL10n.createElement.args.filter(
|
||||
([, el, args]) =>
|
||||
el === "p" && args.classList === "whatsNew-message-date"
|
||||
);
|
||||
assert.lengthOf(dateElements, uniqueDates.length);
|
||||
});
|
||||
it("should listen for panelhidden and remove the toolbar button", async () => {
|
||||
getMessagesStub.returns([]);
|
||||
fakeDocument.getElementById
|
||||
.withArgs("customizationui-widget-panel")
|
||||
.returns(null);
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
assert.notCalled(fakeElementById.addEventListener);
|
||||
});
|
||||
it("should attach doCommand cbs that handle user actions", async () => {
|
||||
const messages = (await PanelTestProvider.getMessages()).filter(
|
||||
m => m.template === "whatsnew_panel_message"
|
||||
);
|
||||
getMessagesStub.returns(messages);
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
const messageEl = createdCustomElements.find(
|
||||
el =>
|
||||
el.tagName === "div" && el.classList.includes("whatsNew-message-body")
|
||||
);
|
||||
const anchorEl = createdCustomElements.find(el => el.tagName === "a");
|
||||
|
||||
assert.notCalled(global.SpecialMessageActions.handleAction);
|
||||
|
||||
messageEl.doCommand();
|
||||
anchorEl.doCommand();
|
||||
|
||||
assert.calledTwice(global.SpecialMessageActions.handleAction);
|
||||
});
|
||||
it("should listen for panelhidden and remove the toolbar button", async () => {
|
||||
getMessagesStub.returns([]);
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
assert.calledOnce(fakeElementById.addEventListener);
|
||||
assert.calledWithExactly(
|
||||
fakeElementById.addEventListener,
|
||||
"popuphidden",
|
||||
sinon.match.func,
|
||||
{
|
||||
once: true,
|
||||
}
|
||||
);
|
||||
const [, cb] = fakeElementById.addEventListener.firstCall.args;
|
||||
|
||||
assert.notCalled(everyWindowStub.unregisterCallback);
|
||||
|
||||
cb();
|
||||
|
||||
assert.calledOnce(everyWindowStub.unregisterCallback);
|
||||
assert.calledWithExactly(
|
||||
everyWindowStub.unregisterCallback,
|
||||
"whats-new-menu-button"
|
||||
);
|
||||
});
|
||||
describe("#IMPRESSION", () => {
|
||||
it("should dispatch a IMPRESSION for messages", async () => {
|
||||
// means panel is triggered from the toolbar button
|
||||
fakeElementById.hasAttribute.returns(true);
|
||||
const messages = (await PanelTestProvider.getMessages()).filter(
|
||||
m => m.template === "whatsnew_panel_message"
|
||||
);
|
||||
getMessagesStub.returns(messages);
|
||||
const spy = sandbox.spy(instance, "sendUserEventTelemetry");
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
assert.calledOnce(spy);
|
||||
assert.calledOnce(fakeSendTelemetry);
|
||||
assert.propertyVal(
|
||||
spy.firstCall.args[2],
|
||||
"id",
|
||||
messages
|
||||
.map(({ id }) => id)
|
||||
.sort()
|
||||
.join(",")
|
||||
);
|
||||
});
|
||||
it("should dispatch a CLICK for clicking a message", async () => {
|
||||
// means panel is triggered from the toolbar button
|
||||
fakeElementById.hasAttribute.returns(true);
|
||||
// Force to render the message
|
||||
fakeElementById.querySelector.returns(null);
|
||||
const messages = (await PanelTestProvider.getMessages()).filter(
|
||||
m => m.template === "whatsnew_panel_message"
|
||||
);
|
||||
getMessagesStub.returns([messages[0]]);
|
||||
const spy = sandbox.spy(instance, "sendUserEventTelemetry");
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
assert.calledOnce(spy);
|
||||
assert.calledOnce(fakeSendTelemetry);
|
||||
|
||||
spy.resetHistory();
|
||||
|
||||
// Message click event listener cb
|
||||
eventListeners.mouseup();
|
||||
|
||||
assert.calledOnce(spy);
|
||||
assert.calledWithExactly(spy, fakeWindow, "CLICK", messages[0]);
|
||||
});
|
||||
it("should dispatch a IMPRESSION with toolbar_dropdown", async () => {
|
||||
// means panel is triggered from the toolbar button
|
||||
fakeElementById.hasAttribute.returns(true);
|
||||
const messages = (await PanelTestProvider.getMessages()).filter(
|
||||
m => m.template === "whatsnew_panel_message"
|
||||
);
|
||||
getMessagesStub.resolves(messages);
|
||||
const spy = sandbox.spy(instance, "sendUserEventTelemetry");
|
||||
const panelPingId = messages
|
||||
.map(({ id }) => id)
|
||||
.sort()
|
||||
.join(",");
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
assert.calledOnce(spy);
|
||||
assert.calledWithExactly(
|
||||
spy,
|
||||
fakeWindow,
|
||||
"IMPRESSION",
|
||||
{
|
||||
id: panelPingId,
|
||||
},
|
||||
{
|
||||
value: {
|
||||
view: "toolbar_dropdown",
|
||||
},
|
||||
}
|
||||
);
|
||||
assert.calledOnce(fakeSendTelemetry);
|
||||
const {
|
||||
args: [dispatchPayload],
|
||||
} = fakeSendTelemetry.lastCall;
|
||||
assert.propertyVal(dispatchPayload, "type", "TOOLBAR_PANEL_TELEMETRY");
|
||||
assert.propertyVal(dispatchPayload.data, "message_id", panelPingId);
|
||||
assert.deepEqual(dispatchPayload.data.event_context, {
|
||||
view: "toolbar_dropdown",
|
||||
});
|
||||
});
|
||||
it("should dispatch a IMPRESSION with application_menu", async () => {
|
||||
// means panel is triggered as a subview in the application menu
|
||||
fakeElementById.hasAttribute.returns(false);
|
||||
const messages = (await PanelTestProvider.getMessages()).filter(
|
||||
m => m.template === "whatsnew_panel_message"
|
||||
);
|
||||
getMessagesStub.resolves(messages);
|
||||
const spy = sandbox.spy(instance, "sendUserEventTelemetry");
|
||||
const panelPingId = messages
|
||||
.map(({ id }) => id)
|
||||
.sort()
|
||||
.join(",");
|
||||
|
||||
await instance.renderMessages(fakeWindow, fakeDocument, "container-id");
|
||||
|
||||
assert.calledOnce(spy);
|
||||
assert.calledWithExactly(
|
||||
spy,
|
||||
fakeWindow,
|
||||
"IMPRESSION",
|
||||
{
|
||||
id: panelPingId,
|
||||
},
|
||||
{
|
||||
value: {
|
||||
view: "application_menu",
|
||||
},
|
||||
}
|
||||
);
|
||||
assert.calledOnce(fakeSendTelemetry);
|
||||
const {
|
||||
args: [dispatchPayload],
|
||||
} = fakeSendTelemetry.lastCall;
|
||||
assert.propertyVal(dispatchPayload, "type", "TOOLBAR_PANEL_TELEMETRY");
|
||||
assert.propertyVal(dispatchPayload.data, "message_id", panelPingId);
|
||||
assert.deepEqual(dispatchPayload.data.event_context, {
|
||||
view: "application_menu",
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("#forceShowMessage", () => {
|
||||
const panelSelector = "PanelUI-whatsNew-message-container";
|
||||
let removeMessagesSpy;
|
||||
let renderMessagesStub;
|
||||
let addEventListenerStub;
|
||||
let messages;
|
||||
let browser;
|
||||
beforeEach(async () => {
|
||||
messages = (await PanelTestProvider.getMessages()).find(
|
||||
m => m.id === "WHATS_NEW_70_1"
|
||||
);
|
||||
removeMessagesSpy = sandbox.spy(instance, "removeMessages");
|
||||
renderMessagesStub = sandbox.spy(instance, "renderMessages");
|
||||
addEventListenerStub = fakeElementById.addEventListener;
|
||||
browser = { ownerGlobal: fakeWindow, ownerDocument: fakeDocument };
|
||||
fakeElementById.querySelectorAll.returns([fakeElementById]);
|
||||
});
|
||||
it("should call removeMessages when forcing a message to show", () => {
|
||||
instance.forceShowMessage(browser, messages);
|
||||
|
||||
assert.calledWithExactly(removeMessagesSpy, fakeWindow, panelSelector);
|
||||
});
|
||||
it("should call renderMessages when forcing a message to show", () => {
|
||||
instance.forceShowMessage(browser, messages);
|
||||
|
||||
assert.calledOnce(renderMessagesStub);
|
||||
assert.calledWithExactly(
|
||||
renderMessagesStub,
|
||||
fakeWindow,
|
||||
fakeDocument,
|
||||
panelSelector,
|
||||
{
|
||||
force: true,
|
||||
messages: Array.isArray(messages) ? messages : [messages],
|
||||
}
|
||||
);
|
||||
});
|
||||
it("should cleanup after the panel is hidden when forcing a message to show", () => {
|
||||
instance.forceShowMessage(browser, messages);
|
||||
|
||||
assert.calledOnce(addEventListenerStub);
|
||||
assert.calledWithExactly(
|
||||
addEventListenerStub,
|
||||
"popuphidden",
|
||||
sinon.match.func
|
||||
);
|
||||
|
||||
const [, cb] = addEventListenerStub.firstCall.args;
|
||||
// Reset the call count from the first `forceShowMessage` call
|
||||
removeMessagesSpy.resetHistory();
|
||||
cb({ target: { ownerGlobal: fakeWindow } });
|
||||
|
||||
assert.calledOnce(removeMessagesSpy);
|
||||
assert.calledWithExactly(removeMessagesSpy, fakeWindow, panelSelector);
|
||||
});
|
||||
it("should exit gracefully if called before a browser exists", () => {
|
||||
instance.forceShowMessage(null, messages);
|
||||
assert.neverCalledWith(removeMessagesSpy, fakeWindow, panelSelector);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -81,10 +81,6 @@ async function makeValidators() {
|
||||
"resource://testing-common/UpdateAction.schema.json",
|
||||
{ common: true }
|
||||
),
|
||||
whatsnew_panel_message: await schemaValidatorFor(
|
||||
"resource://testing-common/WhatsNewMessage.schema.json",
|
||||
{ common: true }
|
||||
),
|
||||
feature_callout: await schemaValidatorFor(
|
||||
// For now, Feature Callout and Spotlight share a common schema
|
||||
"resource://testing-common/Spotlight.schema.json",
|
||||
|
@ -22,7 +22,6 @@ add_task(async function test_PanelTestProvider() {
|
||||
cfr_doorhanger: 1,
|
||||
milestone_message: 0,
|
||||
update_action: 1,
|
||||
whatsnew_panel_message: 7,
|
||||
spotlight: 3,
|
||||
feature_callout: 1,
|
||||
pb_newtab: 2,
|
||||
|
@ -36,8 +36,8 @@
|
||||
</box>
|
||||
<toolbarseparator></toolbarseparator>
|
||||
|
||||
<html:div id="messaging-system-message-container" disabled="true">
|
||||
<!-- Messaging System Messages will render in this container -->
|
||||
<html:div id="info-message-container" disabled="true">
|
||||
<!-- Info message will render in this container -->
|
||||
</html:div>
|
||||
</vbox>
|
||||
|
||||
|
@ -6,7 +6,6 @@ ChromeUtils.defineESModuleGetters(this, {
|
||||
AppMenuNotifications: "resource://gre/modules/AppMenuNotifications.sys.mjs",
|
||||
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
||||
PanelMultiView: "resource:///modules/PanelMultiView.sys.mjs",
|
||||
ToolbarPanelHub: "resource:///modules/asrouter/ToolbarPanelHub.jsm",
|
||||
});
|
||||
|
||||
/**
|
||||
@ -167,9 +166,6 @@ const PanelUI = {
|
||||
this.menuButton.removeEventListener("mousedown", this);
|
||||
this.menuButton.removeEventListener("keypress", this);
|
||||
CustomizableUI.removeListener(this);
|
||||
if (this.whatsNewPanel) {
|
||||
this.whatsNewPanel.removeEventListener("ViewShowing", this);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -303,11 +299,6 @@ const PanelUI = {
|
||||
case "activate":
|
||||
this.updateNotifications();
|
||||
break;
|
||||
case "ViewShowing":
|
||||
if (aEvent.target == this.whatsNewPanel) {
|
||||
this.onWhatsNewPanelShowing();
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
@ -412,7 +403,6 @@ const PanelUI = {
|
||||
return;
|
||||
}
|
||||
|
||||
this.ensureWhatsNewInitialized(viewNode);
|
||||
this.ensurePanicViewInitialized(viewNode);
|
||||
|
||||
let container = aAnchor.closest("panelmultiview");
|
||||
@ -496,24 +486,6 @@ const PanelUI = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets up the event listener for when the What's New panel is shown.
|
||||
*
|
||||
* @param {panelview} panelView The What's New panelview.
|
||||
*/
|
||||
ensureWhatsNewInitialized(panelView) {
|
||||
if (panelView.id != "PanelUI-whatsNew" || panelView._initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.whatsNewPanel) {
|
||||
this.whatsNewPanel = panelView;
|
||||
}
|
||||
|
||||
panelView._initialized = true;
|
||||
panelView.addEventListener("ViewShowing", this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds FTL before appending the panic view markup to the main DOM.
|
||||
*
|
||||
@ -532,17 +504,6 @@ const PanelUI = {
|
||||
panelView._initialized = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* When the What's New panel is showing, we fetch the messages to show.
|
||||
*/
|
||||
onWhatsNewPanelShowing() {
|
||||
ToolbarPanelHub.renderMessages(
|
||||
window,
|
||||
document,
|
||||
"PanelUI-whatsNew-message-container"
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* NB: The enable- and disableSingleSubviewPanelAnimations methods only
|
||||
* affect the hiding/showing animations of single-subview panels (tempPanel
|
||||
|
@ -454,8 +454,7 @@ export class TelemetryFeed {
|
||||
event = await this.applyCFRPolicy(event);
|
||||
break;
|
||||
case "badge_user_event":
|
||||
case "whats-new-panel_user_event":
|
||||
event = await this.applyWhatsNewPolicy(event);
|
||||
event = await this.applyToolbarBadgePolicy(event);
|
||||
break;
|
||||
case "infobar_user_event":
|
||||
event = await this.applyInfoBarPolicy(event);
|
||||
@ -509,12 +508,12 @@ export class TelemetryFeed {
|
||||
* Per Bug 1482134, all the metrics for What's New panel use client_id in
|
||||
* all the release channels
|
||||
*/
|
||||
async applyWhatsNewPolicy(ping) {
|
||||
async applyToolbarBadgePolicy(ping) {
|
||||
ping.client_id = await this.telemetryClientId;
|
||||
ping.browser_session_id = lazy.browserSessionId;
|
||||
// Attach page info to `event_context` if there is a session associated with this ping
|
||||
delete ping.action;
|
||||
return { ping, pingType: "whats-new-panel" };
|
||||
return { ping, pingType: "toolbar-badge" };
|
||||
}
|
||||
|
||||
async applyInfoBarPolicy(ping) {
|
||||
|
@ -1010,7 +1010,7 @@ messaging_system:
|
||||
type: string
|
||||
description: >
|
||||
Type of event the ping is capturing.
|
||||
e.g. "cfr", "whats-new-panel", "onboarding"
|
||||
e.g. "cfr", "onboarding"
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1825863
|
||||
data_reviews:
|
||||
|
@ -947,18 +947,18 @@ add_task(
|
||||
}
|
||||
);
|
||||
|
||||
add_task(async function test_applyWhatsNewPolicy() {
|
||||
add_task(async function test_applyToolbarBadgePolicy() {
|
||||
info(
|
||||
"TelemetryFeed.applyWhatsNewPolicy should set client_id and set pingType"
|
||||
"TelemetryFeed.applyToolbarBadgePolicy should set client_id and set pingType"
|
||||
);
|
||||
let instance = new TelemetryFeed();
|
||||
let { ping, pingType } = await instance.applyWhatsNewPolicy({});
|
||||
let { ping, pingType } = await instance.applyToolbarBadgePolicy({});
|
||||
|
||||
Assert.equal(
|
||||
ping.client_id,
|
||||
Services.prefs.getCharPref("toolkit.telemetry.cachedClientID")
|
||||
);
|
||||
Assert.equal(pingType, "whats-new-panel");
|
||||
Assert.equal(pingType, "toolbar-badge");
|
||||
});
|
||||
|
||||
add_task(async function test_applyInfoBarPolicy() {
|
||||
@ -1288,10 +1288,10 @@ add_task(async function test_createASRouterEvent_call_correctPolicy() {
|
||||
message_id: "onboarding_message_01",
|
||||
});
|
||||
|
||||
testCallCorrectPolicy("applyWhatsNewPolicy", {
|
||||
action: "whats-new-panel_user_event",
|
||||
event: "CLICK_BUTTON",
|
||||
message_id: "whats-new-panel_message_01",
|
||||
testCallCorrectPolicy("applyToolbarBadgePolicy", {
|
||||
action: "badge_user_event",
|
||||
event: "IMPRESSION",
|
||||
message_id: "badge_message_01",
|
||||
});
|
||||
|
||||
testCallCorrectPolicy("applyMomentsPolicy", {
|
||||
|
@ -8,10 +8,6 @@
|
||||
scrollbar-color: color-mix(in srgb, currentColor 26%, transparent) transparent;
|
||||
}
|
||||
|
||||
#appMenu-mainView > .panel-subview-body > .panel-banner-item {
|
||||
padding-inline-start: 18px;
|
||||
}
|
||||
|
||||
.subviewbutton:not([image],[targetURI],.bookmark-item) > .menu-iconic-left {
|
||||
display: none;
|
||||
}
|
||||
|
@ -1655,13 +1655,13 @@ radiogroup:focus-visible > .subviewradio[focused="true"] {
|
||||
}
|
||||
|
||||
#protections-popup {
|
||||
#messaging-system-message-container {
|
||||
#info-message-container {
|
||||
height: 260px;
|
||||
overflow: hidden;
|
||||
transition: margin-bottom .25s;
|
||||
}
|
||||
|
||||
#messaging-system-message-container[disabled] {
|
||||
#info-message-container[disabled] {
|
||||
/* Offset the height when hidden. This makes the panel content
|
||||
* cover the info message and reveal it as it slides down, rather
|
||||
* than the info message growing in height. */
|
||||
@ -1669,7 +1669,7 @@ radiogroup:focus-visible > .subviewradio[focused="true"] {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#messaging-system-message-container[disabled] #protections-popup-message {
|
||||
#info-message-container[disabled] #protections-popup-message {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
@ -451,10 +451,6 @@ toolbarbutton.bookmark-item {
|
||||
list-style-image: url("chrome://global/skin/icons/folder.svg");
|
||||
}
|
||||
|
||||
#whats-new-menu-button {
|
||||
list-style-image: url("chrome://global/skin/icons/whatsnew.svg");
|
||||
}
|
||||
|
||||
#ion-button {
|
||||
list-style-image: url("chrome://browser/skin/ion.svg");
|
||||
}
|
||||
|
@ -116,6 +116,7 @@ devtools.jar:
|
||||
skin/images/import.svg (themes/images/import.svg)
|
||||
skin/images/pane-collapse.svg (themes/images/pane-collapse.svg)
|
||||
skin/images/pane-expand.svg (themes/images/pane-expand.svg)
|
||||
skin/images/whatsnew.svg (themes/images/whatsnew.svg)
|
||||
skin/images/help.svg (themes/images/help.svg)
|
||||
skin/images/report.svg (themes/images/report.svg)
|
||||
skin/images/reveal.svg (themes/images/reveal.svg)
|
||||
|
@ -87,7 +87,7 @@
|
||||
}
|
||||
|
||||
.notificationbox .messageImage[data-type="new"] {
|
||||
background-image: url("chrome://global/skin/icons/whatsnew.svg");
|
||||
background-image: url("chrome://devtools/skin/images/whatsnew.svg");
|
||||
fill: var(--theme-highlight-blue);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 897 B After Width: | Height: | Size: 897 B |
@ -124,7 +124,6 @@
|
||||
skin/classic/global/icons/arrow-up.svg (../../shared/icons/arrow-up.svg)
|
||||
skin/classic/global/icons/warning.svg (../../shared/icons/warning.svg)
|
||||
skin/classic/global/icons/warning-fill-12.svg (../../shared/icons/warning-fill-12.svg)
|
||||
skin/classic/global/icons/whatsnew.svg (../../shared/icons/whatsnew.svg)
|
||||
skin/classic/global/illustrations/about-rights.svg (../../shared/illustrations/about-rights.svg)
|
||||
skin/classic/global/illustrations/about-license.svg (../../shared/illustrations/about-license.svg)
|
||||
skin/classic/global/illustrations/error-malformed-url.svg (../../shared/illustrations/error-malformed-url.svg)
|
||||
|
Loading…
Reference in New Issue
Block a user