tor-browser

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

commit ecfd420667a415fc31d65dbf41a12f33801acd0d
parent 33294a54240daf8cd6d85d0216b0bc77b82ae64f
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 ShortcutFeatureHighlight component r=home-newtab-reviewers,nbarrett

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

Diffstat:
Mbrowser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/ShortcutFeatureHighlight.jsx | 56+++++++++++++++++++++++++++++++++++++++-----------------
Mbrowser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/_ShortcutFeatureHighlight.scss | 23++++++++++++++++++++---
Mbrowser/extensions/newtab/content-src/components/TopSites/TopSite.jsx | 1+
Mbrowser/extensions/newtab/css/activity-stream.css | 14+++++++++++---
Mbrowser/extensions/newtab/data/content/activity-stream.bundle.js | 37+++++++++++++++++++++++++------------
Mbrowser/extensions/newtab/test/unit/content-src/components/DiscoveryStreamComponents/ShortcutFeatureHighlight.test.jsx | 7+++++--
6 files changed, 101 insertions(+), 37 deletions(-)

diff --git a/browser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/ShortcutFeatureHighlight.jsx b/browser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/ShortcutFeatureHighlight.jsx @@ -6,11 +6,12 @@ import React, { useCallback } from "react"; import { FeatureHighlight } from "./FeatureHighlight"; export function ShortcutFeatureHighlight({ - position, dispatch, - handleDismiss, - handleBlock, feature, + handleBlock, + handleDismiss, + messageData, + position, }) { const onDismiss = useCallback(() => { handleDismiss(); @@ -18,28 +19,49 @@ export function ShortcutFeatureHighlight({ }, [handleDismiss, handleBlock]); return ( - <div className="shortcut-feature-highlight"> + <div + className={`shortcut-feature-highlight ${messageData.content?.darkModeDismiss ? "is-inverted-dark-dismiss-button" : ""}`} + > <FeatureHighlight position={position} feature={feature} dispatch={dispatch} message={ <div className="shortcut-feature-highlight-content"> - <img - src="chrome://global/skin/icons/open-in-new.svg" - width="24" - height="24" - alt="" - /> - <div className="shortcut-feature-highlight-copy"> - <p - className="title" - data-l10n-id="newtab-shortcuts-highlight-title" + <picture className="follow-section-button-highlight-image"> + <source + srcSet={ + messageData.content?.darkModeImageURL || + "chrome://newtab/content/data/content/assets/highlights/omc-newtab-shortcuts.svg" + } + media="(prefers-color-scheme: dark)" /> - <p - className="subtitle" - data-l10n-id="newtab-shortcuts-highlight-subtitle" + <source + srcSet={ + messageData.content?.imageURL || + "chrome://newtab/content/data/content/assets/highlights/omc-newtab-shortcuts.svg" + } + media="(prefers-color-scheme: light)" /> + <img width="320" height="195" alt="" /> + </picture> + <div className="shortcut-feature-highlight-copy"> + {messageData.content?.cardTitle ? ( + <p className="title">{messageData.content.cardTitle}</p> + ) : ( + <p + className="title" + data-l10n-id="newtab-shortcuts-highlight-title" + /> + )} + {messageData.content?.cardMessage ? ( + <p className="subtitle">{messageData.content.cardMessage}</p> + ) : ( + <p + className="subtitle" + data-l10n-id="newtab-shortcuts-highlight-subtitle" + /> + )} </div> </div> } diff --git a/browser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/_ShortcutFeatureHighlight.scss b/browser/extensions/newtab/content-src/components/DiscoveryStreamComponents/FeatureHighlight/_ShortcutFeatureHighlight.scss @@ -2,6 +2,7 @@ .shortcut-feature-highlight { .feature-highlight-modal { padding: var(--space-large); + width: auto; p { margin: 0; @@ -22,14 +23,30 @@ inset-inline-end: var(--space-xlarge); } - img { - -moz-context-properties: fill; - fill: currentColor; + // 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); + } + } } } .shortcut-feature-highlight-content { display: flex; + flex-direction: column; gap: var(--space-medium); } diff --git a/browser/extensions/newtab/content-src/components/TopSites/TopSite.jsx b/browser/extensions/newtab/content-src/components/TopSites/TopSite.jsx @@ -445,6 +445,7 @@ export class TopSiteLink extends React.PureComponent { dispatch={this.props.dispatch} feature="FEATURE_SHORTCUT_HIGHLIGHT" position="inset-block-end inset-inline-start" + messageData={this.props.Messages?.messageData} /> </MessageWrapper> )} diff --git a/browser/extensions/newtab/css/activity-stream.css b/browser/extensions/newtab/css/activity-stream.css @@ -8555,6 +8555,7 @@ dialog::after { .shortcut-feature-highlight .feature-highlight-modal { padding: var(--space-large); + width: auto; } .shortcut-feature-highlight .feature-highlight-modal p { margin: 0; @@ -8570,12 +8571,19 @@ dialog::after { margin-block-start: var(--space-large); inset-inline-end: var(--space-xlarge); } -.shortcut-feature-highlight .feature-highlight-modal img { - -moz-context-properties: fill; - fill: currentColor; +.shortcut-feature-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) { + .shortcut-feature-highlight.is-inverted-dark-dismiss-button .feature-highlight-modal > moz-button { + --button-icon-fill: var(--color-gray-70); + } } .shortcut-feature-highlight .shortcut-feature-highlight-content { display: flex; + flex-direction: column; gap: var(--space-medium); } .shortcut-feature-highlight .shortcut-feature-highlight-copy { diff --git a/browser/extensions/newtab/data/content/activity-stream.bundle.js b/browser/extensions/newtab/data/content/activity-stream.bundle.js @@ -8928,35 +8928,47 @@ function FeatureHighlight({ function ShortcutFeatureHighlight({ - position, dispatch, - handleDismiss, + feature, handleBlock, - feature + handleDismiss, + messageData, + position }) { const onDismiss = (0,external_React_namespaceObject.useCallback)(() => { handleDismiss(); handleBlock(); }, [handleDismiss, handleBlock]); return /*#__PURE__*/external_React_default().createElement("div", { - className: "shortcut-feature-highlight" + className: `shortcut-feature-highlight ${messageData.content?.darkModeDismiss ? "is-inverted-dark-dismiss-button" : ""}` }, /*#__PURE__*/external_React_default().createElement(FeatureHighlight, { position: position, feature: feature, dispatch: dispatch, message: /*#__PURE__*/external_React_default().createElement("div", { className: "shortcut-feature-highlight-content" - }, /*#__PURE__*/external_React_default().createElement("img", { - src: "chrome://global/skin/icons/open-in-new.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-shortcuts.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-shortcuts.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: "shortcut-feature-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-shortcuts-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-shortcuts-highlight-subtitle" }))), @@ -9359,7 +9371,8 @@ class TopSiteLink extends (external_React_default()).PureComponent { }, /*#__PURE__*/external_React_default().createElement(ShortcutFeatureHighlight, { dispatch: this.props.dispatch, feature: "FEATURE_SHORTCUT_HIGHLIGHT", - position: "inset-block-end inset-inline-start" + position: "inset-block-end inset-inline-start", + messageData: this.props.Messages?.messageData })), children, impressionStats)); } } diff --git a/browser/extensions/newtab/test/unit/content-src/components/DiscoveryStreamComponents/ShortcutFeatureHighlight.test.jsx b/browser/extensions/newtab/test/unit/content-src/components/DiscoveryStreamComponents/ShortcutFeatureHighlight.test.jsx @@ -8,20 +8,23 @@ describe("Discovery Stream <ShortcutFeatureHighlight>", () => { 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( <ShortcutFeatureHighlight dispatch={dispatch} - handleDismiss={handleDismiss} + feature="FEATURE_SHORTCUT_HIGHLIGHT" handleBlock={handleBlock} + handleDismiss={handleDismiss} + messageData={messageData} position="inset-block-end inset-inline-start" - feature="FEATURE_SHORTCUT_HIGHLIGHT" /> ); });