tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 33294a54240daf8cd6d85d0216b0bc77b82ae64f
parent d93437669de7a0dd10e5903fb3a6dd5f6a15c204
Author: Maxx Crawford <mcrawford@mozilla.com>
Date:   Wed,  1 Oct 2025 14:03:13 +0000

Bug 1991678 - Add remote data support (images, custom text strings) to FollowSectionButtonHighlight component r=home-newtab-reviewers,nbarrett

Differential Revision: https://phabricator.services.mozilla.com/D266885

Diffstat:
Mbrowser/extensions/newtab/content-src/components/DiscoveryStreamComponents/CardSections/CardSections.jsx | 1+
Mbrowser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/FollowSectionButtonHighlight.jsx | 58++++++++++++++++++++++++++++++++++++++++------------------
Mbrowser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/_FollowSectionButtonHighlight.scss | 21+++++++++++++++++++++
Mbrowser/extensions/newtab/css/activity-stream.css | 12++++++++++++
Mbrowser/extensions/newtab/data/content/activity-stream.bundle.js | 39++++++++++++++++++++++++++-------------
Mbrowser/extensions/newtab/test/unit/content-src/components/DiscoveryStreamComponents/FollowSectionButtonHighlight.test.jsx | 11+++++++----
6 files changed, 107 insertions(+), 35 deletions(-)

diff --git a/browser/extensions/newtab/content-src/components/DiscoveryStreamComponents/CardSections/CardSections.jsx b/browser/extensions/newtab/content-src/components/DiscoveryStreamComponents/CardSections/CardSections.jsx @@ -284,6 +284,7 @@ function CardSection({ position="arrow-inline-start" dispatch={dispatch} feature="FEATURE_FOLLOW_SECTION_BUTTON" + messageData={messageData} /> </MessageWrapper> )} diff --git a/browser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/FollowSectionButtonHighlight.jsx b/browser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/FollowSectionButtonHighlight.jsx @@ -7,12 +7,13 @@ import React, { useCallback } from "react"; export function FollowSectionButtonHighlight({ arrowPosition, - position, - verticalPosition, dispatch, - handleDismiss, - handleBlock, feature, + handleBlock, + handleDismiss, + messageData, + position, + verticalPosition, }) { const onDismiss = useCallback(() => { handleDismiss(); @@ -20,7 +21,9 @@ export function FollowSectionButtonHighlight({ }, [handleDismiss, handleBlock]); return ( - <div className="follow-section-button-highlight"> + <div + className={`follow-section-button-highlight ${messageData.content?.darkModeDismiss ? "is-inverted-dark-dismiss-button" : ""}`} + > <FeatureHighlight position={position} arrowPosition={arrowPosition} @@ -29,21 +32,40 @@ export function FollowSectionButtonHighlight({ dispatch={dispatch} message={ <div className="follow-section-button-highlight-content"> - <img - src="chrome://browser/content/asrouter/assets/smiling-fox-icon.svg" - width="24" - height="24" - alt="" - /> - <div className="follow-section-button-highlight-copy"> - <p - className="title" - data-l10n-id="newtab-section-follow-highlight-title" + <picture className="follow-section-button-highlight-image"> + <source + srcSet={ + messageData.content?.darkModeImageURL || + "chrome://newtab/content/data/content/assets/highlights/omc-newtab-follow.svg" + } + media="(prefers-color-scheme: dark)" /> - <p - className="subtitle" - data-l10n-id="newtab-section-follow-highlight-subtitle" + <source + srcSet={ + messageData.content?.imageURL || + "chrome://newtab/content/data/content/assets/highlights/omc-newtab-follow.svg" + } + media="(prefers-color-scheme: light)" /> + <img width="320" height="195" alt="" /> + </picture> + <div className="follow-section-button-highlight-copy"> + {messageData.content?.cardTitle ? ( + <p className="title">{messageData.content.cardTitle}</p> + ) : ( + <p + className="title" + data-l10n-id="newtab-section-follow-highlight-title" + /> + )} + {messageData.content?.cardMessage ? ( + <p className="subtitle">{messageData.content.cardMessage}</p> + ) : ( + <p + className="subtitle" + data-l10n-id="newtab-section-follow-highlight-subtitle" + /> + )} </div> </div> } diff --git a/browser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/_FollowSectionButtonHighlight.scss b/browser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/_FollowSectionButtonHighlight.scss @@ -2,6 +2,7 @@ .follow-section-button-highlight { .feature-highlight-modal { padding: var(--space-large); + width: auto; p { margin: 0; @@ -15,6 +16,25 @@ margin-block-start: 0; margin-inline-end: 0; } + + // The "Dismiss" button in the top right corner of the highlight needs to be in front of the image + > moz-button { + position: absolute; + inset-inline-end: var(--space-large); + inset-block-start: var(--space-large); + } + } + + // Custom override for dismiss-contrast + &.is-inverted-dark-dismiss-button { + .feature-highlight-modal { + @media (prefers-color-scheme: dark) { + // override color so that it is visible on the image + >moz-button { + --button-icon-fill: var(--color-gray-70); + } + } + } } .feature-highlight-modal.arrow-inline-start { @@ -53,6 +73,7 @@ .follow-section-button-highlight-content { display: flex; + flex-direction: column; gap: var(--space-medium); } diff --git a/browser/extensions/newtab/css/activity-stream.css b/browser/extensions/newtab/css/activity-stream.css @@ -8426,6 +8426,7 @@ dialog::after { .follow-section-button-highlight .feature-highlight-modal { padding: var(--space-large); + width: auto; } .follow-section-button-highlight .feature-highlight-modal p { margin: 0; @@ -8437,6 +8438,16 @@ dialog::after { margin-block-start: 0; margin-inline-end: 0; } +.follow-section-button-highlight .feature-highlight-modal > moz-button { + position: absolute; + inset-inline-end: var(--space-large); + inset-block-start: var(--space-large); +} +@media (prefers-color-scheme: dark) { + .follow-section-button-highlight.is-inverted-dark-dismiss-button .feature-highlight-modal > moz-button { + --button-icon-fill: var(--color-gray-70); + } +} .follow-section-button-highlight .feature-highlight-modal.arrow-inline-start { inset-block-start: calc(100% + var(--space-large)); inset-inline-start: 50%; @@ -8468,6 +8479,7 @@ dialog::after { } .follow-section-button-highlight .follow-section-button-highlight-content { display: flex; + flex-direction: column; gap: var(--space-medium); } .follow-section-button-highlight .follow-section-button-highlight-copy { diff --git a/browser/extensions/newtab/data/content/activity-stream.bundle.js b/browser/extensions/newtab/data/content/activity-stream.bundle.js @@ -11462,19 +11462,20 @@ const PersonalizedCard = ({ function FollowSectionButtonHighlight({ arrowPosition, - position, - verticalPosition, dispatch, - handleDismiss, + feature, handleBlock, - feature + handleDismiss, + messageData, + position, + verticalPosition }) { const onDismiss = (0,external_React_namespaceObject.useCallback)(() => { handleDismiss(); handleBlock(); }, [handleDismiss, handleBlock]); return /*#__PURE__*/external_React_default().createElement("div", { - className: "follow-section-button-highlight" + className: `follow-section-button-highlight ${messageData.content?.darkModeDismiss ? "is-inverted-dark-dismiss-button" : ""}` }, /*#__PURE__*/external_React_default().createElement(FeatureHighlight, { position: position, arrowPosition: arrowPosition, @@ -11483,17 +11484,28 @@ function FollowSectionButtonHighlight({ dispatch: dispatch, message: /*#__PURE__*/external_React_default().createElement("div", { className: "follow-section-button-highlight-content" - }, /*#__PURE__*/external_React_default().createElement("img", { - src: "chrome://browser/content/asrouter/assets/smiling-fox-icon.svg", - width: "24", - height: "24", + }, /*#__PURE__*/external_React_default().createElement("picture", { + className: "follow-section-button-highlight-image" + }, /*#__PURE__*/external_React_default().createElement("source", { + srcSet: messageData.content?.darkModeImageURL || "chrome://newtab/content/data/content/assets/highlights/omc-newtab-follow.svg", + media: "(prefers-color-scheme: dark)" + }), /*#__PURE__*/external_React_default().createElement("source", { + srcSet: messageData.content?.imageURL || "chrome://newtab/content/data/content/assets/highlights/omc-newtab-follow.svg", + media: "(prefers-color-scheme: light)" + }), /*#__PURE__*/external_React_default().createElement("img", { + width: "320", + height: "195", alt: "" - }), /*#__PURE__*/external_React_default().createElement("div", { + })), /*#__PURE__*/external_React_default().createElement("div", { className: "follow-section-button-highlight-copy" - }, /*#__PURE__*/external_React_default().createElement("p", { + }, messageData.content?.cardTitle ? /*#__PURE__*/external_React_default().createElement("p", { + className: "title" + }, messageData.content.cardTitle) : /*#__PURE__*/external_React_default().createElement("p", { className: "title", "data-l10n-id": "newtab-section-follow-highlight-title" - }), /*#__PURE__*/external_React_default().createElement("p", { + }), messageData.content?.cardMessage ? /*#__PURE__*/external_React_default().createElement("p", { + className: "subtitle" + }, messageData.content.cardMessage) : /*#__PURE__*/external_React_default().createElement("p", { className: "subtitle", "data-l10n-id": "newtab-section-follow-highlight-subtitle" }))), @@ -12203,7 +12215,8 @@ function CardSection({ verticalPosition: "inset-block-center", position: "arrow-inline-start", dispatch: dispatch, - feature: "FEATURE_FOLLOW_SECTION_BUTTON" + feature: "FEATURE_FOLLOW_SECTION_BUTTON", + messageData: messageData })), !anySectionsFollowed && sectionPosition === 1 && shouldShowOMCHighlight(messageData, "FollowSectionButtonAltHighlight") && /*#__PURE__*/external_React_default().createElement(MessageWrapper, { dispatch: dispatch }, /*#__PURE__*/external_React_default().createElement(FollowSectionButtonHighlight, { diff --git a/browser/extensions/newtab/test/unit/content-src/components/DiscoveryStreamComponents/FollowSectionButtonHighlight.test.jsx b/browser/extensions/newtab/test/unit/content-src/components/DiscoveryStreamComponents/FollowSectionButtonHighlight.test.jsx @@ -8,23 +8,26 @@ describe("Discovery Stream <FollowSectionButtonHighlight>", () => { let dispatch; let handleDismiss; let handleBlock; + let messageData; beforeEach(() => { sandbox = sinon.createSandbox(); dispatch = sandbox.stub(); handleDismiss = sandbox.stub(); handleBlock = sandbox.stub(); + messageData = sandbox.stub(); wrapper = mount( <FollowSectionButtonHighlight + arrowPosition="arrow-inline-start" dispatch={dispatch} - handleDismiss={handleDismiss} + feature="FEATURE_FOLLOW_SECTION_BUTTON" handleBlock={handleBlock} + handleDismiss={handleDismiss} isIntersecting={false} - arrowPosition="arrow-inline-start" - verticalPosition="inset-block-center" + messageData={messageData} position="inset-inline-end" - feature="FEATURE_FOLLOW_SECTION_BUTTON" + verticalPosition="inset-block-center" /> ); });