diff --git a/browser/components/aboutwelcome/content-src/components/SubmenuButton.jsx b/browser/components/aboutwelcome/content-src/components/SubmenuButton.jsx
index e0c8144e73c5..e5093b104609 100644
--- a/browser/components/aboutwelcome/content-src/components/SubmenuButton.jsx
+++ b/browser/components/aboutwelcome/content-src/components/SubmenuButton.jsx
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
-import React, { useEffect, useRef, useCallback } from "react";
+import React, { useEffect, useRef, useCallback, useState } from "react";
import { Localized } from "./MSLocalized";
export const SubmenuButton = props => {
@@ -75,6 +75,7 @@ function addMenuitems(items, popup) {
const SubmenuButtonInner = ({ content, handleAction }) => {
const ref = useRef(null);
+ const [isSubmenuExpanded, setIsSubmenuExpanded] = useState(false);
const isPrimary = content.submenu_button?.style === "primary";
const onCommand = useCallback(
event => {
@@ -121,11 +122,13 @@ const SubmenuButtonInner = ({ content, handleAction }) => {
menupopup.addEventListener("popupshowing", event => {
if (event.target === menupopup && event.target.anchorNode) {
event.target.anchorNode.toggleAttribute("open", true);
+ setIsSubmenuExpanded(true);
}
});
menupopup.addEventListener("popuphiding", event => {
if (event.target === menupopup && event.target.anchorNode) {
event.target.anchorNode.toggleAttribute("open", false);
+ setIsSubmenuExpanded(false);
}
});
menupopup.listenersRegistered = true;
@@ -143,6 +146,8 @@ const SubmenuButtonInner = ({ content, handleAction }) => {
value="submenu_button"
onClick={onClick}
ref={ref}
+ aria-haspopup="menu"
+ aria-expanded={isSubmenuExpanded}
/>
);
diff --git a/browser/components/aboutwelcome/content/aboutwelcome.bundle.js b/browser/components/aboutwelcome/content/aboutwelcome.bundle.js
index 85b38a690269..ffb8baa84492 100644
--- a/browser/components/aboutwelcome/content/aboutwelcome.bundle.js
+++ b/browser/components/aboutwelcome/content/aboutwelcome.bundle.js
@@ -2216,6 +2216,7 @@ const SubmenuButtonInner = ({
handleAction
}) => {
const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
+ const [isSubmenuExpanded, setIsSubmenuExpanded] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
const isPrimary = content.submenu_button?.style === "primary";
const onCommand = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(event => {
let {
@@ -2259,11 +2260,13 @@ const SubmenuButtonInner = ({
menupopup.addEventListener("popupshowing", event => {
if (event.target === menupopup && event.target.anchorNode) {
event.target.anchorNode.toggleAttribute("open", true);
+ setIsSubmenuExpanded(true);
}
});
menupopup.addEventListener("popuphiding", event => {
if (event.target === menupopup && event.target.anchorNode) {
event.target.anchorNode.toggleAttribute("open", false);
+ setIsSubmenuExpanded(false);
}
});
menupopup.listenersRegistered = true;
@@ -2280,7 +2283,9 @@ const SubmenuButtonInner = ({
className: `submenu-button ${isPrimary ? "primary" : "secondary"}`,
value: "submenu_button",
onClick: onClick,
- ref: ref
+ ref: ref,
+ "aria-haspopup": "menu",
+ "aria-expanded": isSubmenuExpanded
}));
};
diff --git a/browser/components/asrouter/content/assets/fox-question-mark-icon.svg b/browser/components/asrouter/content/assets/fox-question-mark-icon.svg
new file mode 100644
index 000000000000..46815b1a777e
--- /dev/null
+++ b/browser/components/asrouter/content/assets/fox-question-mark-icon.svg
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/browser/components/asrouter/jar.mn b/browser/components/asrouter/jar.mn
index bd70a03fe91c..17d79a3fb56f 100644
--- a/browser/components/asrouter/jar.mn
+++ b/browser/components/asrouter/jar.mn
@@ -19,3 +19,4 @@ browser.jar:
content/browser/asrouter/assets/fox-with-mobile.svg (content/assets/fox-with-mobile.svg)
content/browser/asrouter/assets/glyph-cfr-feature-16.svg (content/assets/glyph-cfr-feature-16.svg)
content/browser/asrouter/assets/smiling-fox-icon.svg (content/assets/smiling-fox-icon.svg)
+ content/browser/asrouter/assets/fox-question-mark-icon.svg (content/assets/fox-question-mark-icon.svg)
diff --git a/browser/components/asrouter/modules/FeatureCalloutMessages.sys.mjs b/browser/components/asrouter/modules/FeatureCalloutMessages.sys.mjs
index a56323384395..56457ff5c880 100644
--- a/browser/components/asrouter/modules/FeatureCalloutMessages.sys.mjs
+++ b/browser/components/asrouter/modules/FeatureCalloutMessages.sys.mjs
@@ -1409,6 +1409,169 @@ const MESSAGES = () => {
},
targeting: `'cookiebanners.ui.desktop.enabled'|preferenceValue == true && 'cookiebanners.ui.desktop.showCallout'|preferenceValue == true && 'browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features' | preferenceValue != false`,
},
+ {
+ id: "FX_VIEW_DISCOVERABILITY_ALL_USERS",
+ template: "feature_callout",
+ groups: ["cfr"],
+ skip_in_tests:
+ "it fails unrelated tests (browser_asrouter_group_userprefs)",
+ content: {
+ id: "FX_VIEW_DISCOVERABILITY_ALL_USERS",
+ template: "multistage",
+ backdrop: "transparent",
+ transitions: false,
+ screens: [
+ {
+ id: "FX_VIEW_DISCOVERABILITY_ALL_USERS_SCREEN",
+ anchors: [
+ {
+ selector: "#firefox-view-button",
+ panel_position: {
+ anchor_attachment: "bottomcenter",
+ callout_attachment: "topleft",
+ },
+ no_open_on_anchor: true,
+ arrow_width: "15.5563",
+ },
+ ],
+ content: {
+ position: "callout",
+ width: "342px",
+ padding: 16,
+ page_event_listeners: [
+ {
+ params: {
+ type: "click",
+ selectors: "#firefox-view-button",
+ },
+ action: {
+ dismiss: true,
+ },
+ },
+ ],
+ title_logo: {
+ imageURL:
+ "chrome://browser/content/asrouter/assets/fox-question-mark-icon.svg",
+ width: "25px",
+ height: "29px",
+ marginInline: "4px 14px",
+ alignment: "top",
+ },
+ title: {
+ string_id: "fx-view-discoverability-title",
+ marginInline: "0 16px",
+ },
+ subtitle: {
+ string_id: "fx-view-discoverability-subtitle",
+ paddingInline: "34px 0",
+ marginBlock: "-8px -4px",
+ },
+ additional_button: {
+ label: {
+ string_id: "fx-view-discoverability-secondary-button-label",
+ },
+ style: "secondary",
+ action: {
+ type: "BLOCK_MESSAGE",
+ data: {
+ id: "FX_VIEW_DISCOVERABILITY_ALL_USERS",
+ },
+ dismiss: true,
+ },
+ },
+ secondary_button: {
+ label: {
+ string_id: "fx-view-discoverability-primary-button-label",
+ },
+ style: "primary",
+ action: {
+ type: "OPEN_FIREFOX_VIEW",
+ navigate: true,
+ },
+ },
+ submenu_button: {
+ label: {
+ string_id: "split-dismiss-button-chevron",
+ },
+ submenu: [
+ {
+ type: "action",
+ label: {
+ string_id: "split-dismiss-button-dont-show-option",
+ },
+ action: {
+ type: "BLOCK_MESSAGE",
+ data: {
+ id: "FX_VIEW_DISCOVERABILITY_ALL_USERS",
+ },
+ dismiss: true,
+ },
+ id: "block_recommendation",
+ },
+ {
+ type: "action",
+ label: {
+ string_id: "split-dismiss-button-show-fewer-option",
+ },
+ action: {
+ type: "MULTI_ACTION",
+ dismiss: true,
+ data: {
+ actions: [
+ {
+ type: "SET_PREF",
+ data: {
+ pref: {
+ name: "messaging-system-action.firefox-view-recommendations",
+ value: true,
+ },
+ },
+ },
+ {
+ type: "BLOCK_MESSAGE",
+ data: {
+ id: "FX_VIEW_DISCOVERABILITY_ALL_USERS",
+ },
+ },
+ ],
+ },
+ },
+ id: "show_fewer_recommendations",
+ },
+ {
+ type: "separator",
+ },
+ {
+ type: "action",
+ label: {
+ string_id: "split-dismiss-button-manage-settings-option",
+ },
+ action: {
+ type: "OPEN_ABOUT_PAGE",
+ data: {
+ args: "preferences#general-cfrfeatures",
+ where: "tab",
+ },
+ dismiss: true,
+ },
+ id: "manage_settings",
+ },
+ ],
+ attached_to: "additional_button",
+ },
+ },
+ },
+ ],
+ },
+ frequency: {
+ lifetime: 1,
+ },
+ targeting:
+ "!isMajorUpgrade && !willShowDefaultPrompt && !activeNotifications && previousSessionEnd && fxViewButtonAreaType != null && tabsClosedCount >= 5 && 'browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features' | preferenceValue != false",
+ trigger: {
+ id: "nthTabClosed",
+ },
+ },
];
messages = add24HourImpressionJEXLTargeting(
["FIREFOX_VIEW_TAB_PICKUP_REMINDER"],
diff --git a/browser/components/asrouter/tests/browser/browser_feature_callout_panel.js b/browser/components/asrouter/tests/browser/browser_feature_callout_panel.js
index 366f900dafdf..f94b9ace4371 100644
--- a/browser/components/asrouter/tests/browser/browser_feature_callout_panel.js
+++ b/browser/components/asrouter/tests/browser/browser_feature_callout_panel.js
@@ -280,11 +280,25 @@ add_task(async function feature_callout_split_dismiss_button() {
ok(secondaryButton, "Callout should have a split secondary button");
ok(submenuButton, "Callout should have a split submenu button");
ok(submenu, "Callout should have a submenu");
+ is(
+ submenuButton.getAttribute("aria-expanded"),
+ "false",
+ "Submenu aria-expanded attribute should be false by default"
+ );
+ ok(
+ submenuButton.getAttribute("aria-haspopup"),
+ "Submenu should have aria-haspopup attribute"
+ );
// Click the submenu button and wait for the submenu (menupopup) to open.
let opened = BrowserTestUtils.waitForEvent(submenu, "popupshown");
submenuButton.click();
await opened;
+ is(
+ submenuButton.getAttribute("aria-expanded"),
+ "true",
+ "Submenu aria-expanded attribute should be true"
+ );
// Assert that all the menu items are present and that the order and
// structure is correct.
diff --git a/browser/locales/en-US/browser/featureCallout.ftl b/browser/locales/en-US/browser/featureCallout.ftl
index 031eaef84969..245d067052a2 100644
--- a/browser/locales/en-US/browser/featureCallout.ftl
+++ b/browser/locales/en-US/browser/featureCallout.ftl
@@ -62,15 +62,6 @@ fx-view-discoverability-subtitle = Find and reopen it quickly here. We keep a hi
fx-view-discoverability-primary-button-label = Open { -firefoxview-brand-name }
fx-view-discoverability-secondary-button-label = Dismiss
-## Split Dismiss Button Labels
-
-# Blocks the message from showing again
-split-dismiss-button-dont-show-option-label = Don’t show this recommendation again
-# Dismisses message and reduces frequency of message
-split-dismiss-button-show-fewer-option-label = Show fewer recommendations
-# Opens about:preferences#general-cfrfeatures
-split-dismiss-button-manage-settings-option-label = Manage settings
-
## Sidebar Strings
sidebar-button-callout-title = Show tab titles in the sidebar
@@ -108,3 +99,18 @@ sidebar-genai-survey-satisfaction-question = How satisfied are you with having a
sidebar-genai-survey-productive-question =
To what extent do you agree or disagree with this statement:
“The AI chatbot in the sidebar helps me be more productive”?
+
+## Split Dismiss Button Labels
+
+# Blocks the message from showing again
+split-dismiss-button-dont-show-option =
+ .label = Don’t show this recommendation again
+# Dismisses message and reduces frequency of message
+split-dismiss-button-show-fewer-option =
+ .label = Show fewer recommendations
+# Opens about:preferences#general-cfrfeatures
+split-dismiss-button-manage-settings-option =
+ .label = Manage settings
+# Attached to the chevron in the split dismiss submenu button
+split-dismiss-button-chevron =
+ .aria-label = More options
diff --git a/python/l10n/fluent_migrations/bug_1919598_firefoxview_split_dismiss_migrations.py b/python/l10n/fluent_migrations/bug_1919598_firefoxview_split_dismiss_migrations.py
new file mode 100644
index 000000000000..16af94f563d2
--- /dev/null
+++ b/python/l10n/fluent_migrations/bug_1919598_firefoxview_split_dismiss_migrations.py
@@ -0,0 +1,28 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+from fluent.migrate.helpers import transforms_from
+
+
+def migrate(ctx):
+ """Bug 1919598 - Land Firefox View Discoverability treatment-b in mc-, part {index}."""
+
+ target = "browser/browser/featureCallout.ftl"
+
+ ctx.add_transforms(
+ target,
+ target,
+ transforms_from(
+ """
+split-dismiss-button-dont-show-option =
+ .label = {COPY_PATTERN(from_path, "split-dismiss-button-dont-show-option-label")}
+
+split-dismiss-button-show-fewer-option =
+ .label = {COPY_PATTERN(from_path, "split-dismiss-button-show-fewer-option-label")}
+
+split-dismiss-button-manage-settings-option =
+ .label = {COPY_PATTERN(from_path, "split-dismiss-button-manage-settings-option-label")}
+""",
+ from_path=target,
+ ),
+ )