From 086c044dc34dfc0f74fbe41f4ecb402b2cd34884 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:13:33 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- .../asrouter/content-src/asrouter-utils.js | 79 --------------- .../asrouter/content-src/asrouter-utils.mjs | 81 +++++++++++++++ .../components/ASRouterAdmin/ASRouterAdmin.jsx | 25 ++--- .../components/ASRouterAdmin/CopyButton.jsx | 2 +- .../ConditionalWrapper/ConditionalWrapper.jsx | 9 -- .../ImpressionsWrapper/ImpressionsWrapper.jsx | 76 -------------- .../schemas/MessagingExperiment.schema.json | 4 + .../asrouter/content-src/schemas/message-format.md | 111 --------------------- .../asrouter/content-src/styles/_shopping.scss | 1 + .../OnboardingMessage/Spotlight.schema.json | 4 + 10 files changed, 102 insertions(+), 290 deletions(-) delete mode 100644 browser/components/asrouter/content-src/asrouter-utils.js create mode 100644 browser/components/asrouter/content-src/asrouter-utils.mjs delete mode 100644 browser/components/asrouter/content-src/components/ConditionalWrapper/ConditionalWrapper.jsx delete mode 100644 browser/components/asrouter/content-src/components/ImpressionsWrapper/ImpressionsWrapper.jsx delete mode 100644 browser/components/asrouter/content-src/schemas/message-format.md (limited to 'browser/components/asrouter/content-src') diff --git a/browser/components/asrouter/content-src/asrouter-utils.js b/browser/components/asrouter/content-src/asrouter-utils.js deleted file mode 100644 index 65d25cb907..0000000000 --- a/browser/components/asrouter/content-src/asrouter-utils.js +++ /dev/null @@ -1,79 +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/. */ - -import { MESSAGE_TYPE_HASH as msg } from "modules/ActorConstants.sys.mjs"; -import { actionCreators as ac } from "common/Actions.sys.mjs"; - -export const ASRouterUtils = { - addListener(listener) { - if (global.ASRouterAddParentListener) { - global.ASRouterAddParentListener(listener); - } - }, - removeListener(listener) { - if (global.ASRouterRemoveParentListener) { - global.ASRouterRemoveParentListener(listener); - } - }, - sendMessage(action) { - if (global.ASRouterMessage) { - return global.ASRouterMessage(action); - } - throw new Error(`Unexpected call:\n${JSON.stringify(action, null, 3)}`); - }, - blockById(id, options) { - return ASRouterUtils.sendMessage({ - type: msg.BLOCK_MESSAGE_BY_ID, - data: { id, ...options }, - }); - }, - modifyMessageJson(content) { - return ASRouterUtils.sendMessage({ - type: msg.MODIFY_MESSAGE_JSON, - data: { content }, - }); - }, - executeAction(button_action) { - return ASRouterUtils.sendMessage({ - type: msg.USER_ACTION, - data: button_action, - }); - }, - unblockById(id) { - return ASRouterUtils.sendMessage({ - type: msg.UNBLOCK_MESSAGE_BY_ID, - data: { id }, - }); - }, - blockBundle(bundle) { - return ASRouterUtils.sendMessage({ - type: msg.BLOCK_BUNDLE, - data: { bundle }, - }); - }, - unblockBundle(bundle) { - return ASRouterUtils.sendMessage({ - type: msg.UNBLOCK_BUNDLE, - data: { bundle }, - }); - }, - overrideMessage(id) { - return ASRouterUtils.sendMessage({ - type: msg.OVERRIDE_MESSAGE, - data: { id }, - }); - }, - editState(key, value) { - return ASRouterUtils.sendMessage({ - type: msg.EDIT_STATE, - data: { [key]: value }, - }); - }, - sendTelemetry(ping) { - return ASRouterUtils.sendMessage(ac.ASRouterUserEvent(ping)); - }, - getPreviewEndpoint() { - return null; - }, -}; diff --git a/browser/components/asrouter/content-src/asrouter-utils.mjs b/browser/components/asrouter/content-src/asrouter-utils.mjs new file mode 100644 index 0000000000..989d864e71 --- /dev/null +++ b/browser/components/asrouter/content-src/asrouter-utils.mjs @@ -0,0 +1,81 @@ +/* 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/. */ + +// eslint-disable-next-line mozilla/reject-import-system-module-from-non-system +import { MESSAGE_TYPE_HASH as msg } from "../modules/ActorConstants.sys.mjs"; +// eslint-disable-next-line mozilla/reject-import-system-module-from-non-system +import { actionCreators as ac } from "../../newtab/common/Actions.sys.mjs"; + +export const ASRouterUtils = { + addListener(listener) { + if (globalThis.ASRouterAddParentListener) { + globalThis.ASRouterAddParentListener(listener); + } + }, + removeListener(listener) { + if (globalThis.ASRouterRemoveParentListener) { + globalThis.ASRouterRemoveParentListener(listener); + } + }, + sendMessage(action) { + if (globalThis.ASRouterMessage) { + return globalThis.ASRouterMessage(action); + } + throw new Error(`Unexpected call:\n${JSON.stringify(action, null, 3)}`); + }, + blockById(id, options) { + return ASRouterUtils.sendMessage({ + type: msg.BLOCK_MESSAGE_BY_ID, + data: { id, ...options }, + }); + }, + modifyMessageJson(content) { + return ASRouterUtils.sendMessage({ + type: msg.MODIFY_MESSAGE_JSON, + data: { content }, + }); + }, + executeAction(button_action) { + return ASRouterUtils.sendMessage({ + type: msg.USER_ACTION, + data: button_action, + }); + }, + unblockById(id) { + return ASRouterUtils.sendMessage({ + type: msg.UNBLOCK_MESSAGE_BY_ID, + data: { id }, + }); + }, + blockBundle(bundle) { + return ASRouterUtils.sendMessage({ + type: msg.BLOCK_BUNDLE, + data: { bundle }, + }); + }, + unblockBundle(bundle) { + return ASRouterUtils.sendMessage({ + type: msg.UNBLOCK_BUNDLE, + data: { bundle }, + }); + }, + overrideMessage(id) { + return ASRouterUtils.sendMessage({ + type: msg.OVERRIDE_MESSAGE, + data: { id }, + }); + }, + editState(key, value) { + return ASRouterUtils.sendMessage({ + type: msg.EDIT_STATE, + data: { [key]: value }, + }); + }, + sendTelemetry(ping) { + return ASRouterUtils.sendMessage(ac.ASRouterUserEvent(ping)); + }, + getPreviewEndpoint() { + return null; + }, +}; diff --git a/browser/components/asrouter/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx b/browser/components/asrouter/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx index f16dbacbd8..befce707ef 100644 --- a/browser/components/asrouter/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx +++ b/browser/components/asrouter/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx @@ -258,7 +258,7 @@ export class ASRouterAdminInner extends React.PureComponent { ASRouterUtils.sendMessage({ type: "RESET_PROVIDER_PREF" }); } - resetGroups(id, value) { + resetGroups() { ASRouterUtils.sendMessage({ type: "RESET_GROUPS_STATE", }).then(this.setStateFromParent); @@ -387,7 +387,7 @@ export class ASRouterAdminInner extends React.PureComponent { } // Simulate a copy event that sets to clipboard all targeting paramters and values - onCopyTargetingParams(event) { + onCopyTargetingParams() { const stringTargetingParameters = { ...this.state.stringTargetingParameters, }; @@ -507,7 +507,7 @@ export class ASRouterAdminInner extends React.PureComponent { isBlocked ? null : isModified ? ( @@ -523,7 +523,7 @@ export class ASRouterAdminInner extends React.PureComponent { {isBlocked ? null : ( @@ -557,7 +557,7 @@ export class ASRouterAdminInner extends React.PureComponent { name={msg.id} className="general-textarea" disabled={isBlocked} - onChange={e => this.handleChange(msg.id)} + onChange={() => this.handleChange(msg.id)} > {JSON.stringify(msg, null, 2)} @@ -647,7 +647,7 @@ export class ASRouterAdminInner extends React.PureComponent { @@ -698,7 +698,7 @@ export class ASRouterAdminInner extends React.PureComponent {
@@ -1046,7 +1046,7 @@ export class ASRouterAdminInner extends React.PureComponent { }); } - setAttribution(e) { + setAttribution() { ASRouterUtils.sendMessage({ type: "FORCE_ATTRIBUTION", data: this.state.attributionParameters, @@ -1307,7 +1307,7 @@ export class ASRouterAdminInner extends React.PureComponent {

Messages

@@ -1359,10 +1359,7 @@ export class ASRouterAdminInner extends React.PureComponent { {this.state.groups && this.state.groups.map( - ( - { id, enabled, frequency, userPreferences = [] }, - index - ) => ( + ({ id, enabled, frequency, userPreferences = [] }) => ( documentation diff --git a/browser/components/asrouter/content-src/components/ASRouterAdmin/CopyButton.jsx b/browser/components/asrouter/content-src/components/ASRouterAdmin/CopyButton.jsx index 6739d38b97..3233b42032 100644 --- a/browser/components/asrouter/content-src/components/ASRouterAdmin/CopyButton.jsx +++ b/browser/components/asrouter/content-src/components/ASRouterAdmin/CopyButton.jsx @@ -26,7 +26,7 @@ export const CopyButton = ({ timeout.current = setTimeout(() => setCopied(false), 1500); }, [inputSelector, transformer]); return ( - ); diff --git a/browser/components/asrouter/content-src/components/ConditionalWrapper/ConditionalWrapper.jsx b/browser/components/asrouter/content-src/components/ConditionalWrapper/ConditionalWrapper.jsx deleted file mode 100644 index e4b0812f26..0000000000 --- a/browser/components/asrouter/content-src/components/ConditionalWrapper/ConditionalWrapper.jsx +++ /dev/null @@ -1,9 +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/. */ - -// lifted from https://gist.github.com/kitze/23d82bb9eb0baabfd03a6a720b1d637f -const ConditionalWrapper = ({ condition, wrap, children }) => - condition && wrap ? wrap(children) : children; - -export default ConditionalWrapper; diff --git a/browser/components/asrouter/content-src/components/ImpressionsWrapper/ImpressionsWrapper.jsx b/browser/components/asrouter/content-src/components/ImpressionsWrapper/ImpressionsWrapper.jsx deleted file mode 100644 index 8498bde03b..0000000000 --- a/browser/components/asrouter/content-src/components/ImpressionsWrapper/ImpressionsWrapper.jsx +++ /dev/null @@ -1,76 +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/. */ - -import React from "react"; - -export const VISIBLE = "visible"; -export const VISIBILITY_CHANGE_EVENT = "visibilitychange"; - -/** - * Component wrapper used to send telemetry pings on every impression. - */ -export class ImpressionsWrapper extends React.PureComponent { - // This sends an event when a user sees a set of new content. If content - // changes while the page is hidden (i.e. preloaded or on a hidden tab), - // only send the event if the page becomes visible again. - sendImpressionOrAddListener() { - if (this.props.document.visibilityState === VISIBLE) { - this.props.sendImpression({ id: this.props.id }); - } else { - // We should only ever send the latest impression stats ping, so remove any - // older listeners. - if (this._onVisibilityChange) { - this.props.document.removeEventListener( - VISIBILITY_CHANGE_EVENT, - this._onVisibilityChange - ); - } - - // When the page becomes visible, send the impression stats ping if the section isn't collapsed. - this._onVisibilityChange = () => { - if (this.props.document.visibilityState === VISIBLE) { - this.props.sendImpression({ id: this.props.id }); - this.props.document.removeEventListener( - VISIBILITY_CHANGE_EVENT, - this._onVisibilityChange - ); - } - }; - this.props.document.addEventListener( - VISIBILITY_CHANGE_EVENT, - this._onVisibilityChange - ); - } - } - - componentWillUnmount() { - if (this._onVisibilityChange) { - this.props.document.removeEventListener( - VISIBILITY_CHANGE_EVENT, - this._onVisibilityChange - ); - } - } - - componentDidMount() { - if (this.props.sendOnMount) { - this.sendImpressionOrAddListener(); - } - } - - componentDidUpdate(prevProps) { - if (this.props.shouldSendImpressionOnUpdate(this.props, prevProps)) { - this.sendImpressionOrAddListener(); - } - } - - render() { - return this.props.children; - } -} - -ImpressionsWrapper.defaultProps = { - document: global.document, - sendOnMount: true, -}; diff --git a/browser/components/asrouter/content-src/schemas/MessagingExperiment.schema.json b/browser/components/asrouter/content-src/schemas/MessagingExperiment.schema.json index a395f4f990..fbabb109f8 100644 --- a/browser/components/asrouter/content-src/schemas/MessagingExperiment.schema.json +++ b/browser/components/asrouter/content-src/schemas/MessagingExperiment.schema.json @@ -752,6 +752,10 @@ "startScreen": { "type": "integer", "description": "Index of first screen to show from message, defaulting to 0" + }, + "no-rdm": { + "type": "boolean", + "description": "If true, prevents the spotlight from entering responsive design mode at widths less than 800px" } }, "additionalProperties": true diff --git a/browser/components/asrouter/content-src/schemas/message-format.md b/browser/components/asrouter/content-src/schemas/message-format.md deleted file mode 100644 index 65f031e260..0000000000 --- a/browser/components/asrouter/content-src/schemas/message-format.md +++ /dev/null @@ -1,111 +0,0 @@ -## Activity Stream Router message format - -Field name | Type | Required | Description | Example / Note ---- | --- | --- | --- | --- -`id` | `string` | Yes | A unique identifier for the message that should not conflict with any other previous message | `ONBOARDING_1` -`template` | `string` | Yes | An id matching an existing Activity Stream Router template | -`content` | `object` | Yes | An object containing all variables/props to be rendered in the template. Subset of allowed tags detailed below. | [See example below](#html-subset) -`bundled` | `integer` | No | The number of messages of the same template this one should be shown with | [See example below](#a-bundled-message-example) -`order` | `integer` | No | If bundled with other messages of the same template, which order should this one be placed in? Defaults to 0 if no order is desired | [See example below](#a-bundled-message-example) -`campaign` | `string` | No | Campaign id that the message belongs to | `RustWebAssembly` -`targeting` | `string` `JEXL` | No | A [JEXL expression](http://normandy.readthedocs.io/en/latest/user/filter_expressions.html#jexl-basics) with all targeting information needed in order to decide if the message is shown | Not yet implemented, [Examples](#targeting-attributes) -`trigger` | `string` | No | An event or condition upon which the message will be immediately shown. This can be combined with `targeting`. Messages that define a trigger will not be shown during non-trigger-based passive message rotation. -`trigger.params` | `[string]` | No | A set of hostnames passed down as parameters to the trigger condition. Used to restrict the number of domains where the trigger/message is valid. | [See example below](#trigger-params) -`trigger.patterns` | `[string]` | No | A set of patterns that match multiple hostnames passed down as parameters to the trigger condition. Used to restrict the number of domains where the trigger/message is valid. | [See example below](#trigger-patterns) -`frequency` | `object` | No | A definition for frequency cap information for the message -`frequency.lifetime` | `integer` | No | The maximum number of lifetime impressions for the message. -`frequency.custom` | `array` | No | An array of frequency cap definition objects including `period`, a time period in milliseconds, and `cap`, a max number of impressions for that period. - -### Message example -```javascript -{ - weight: 100, - id: "PROTECTIONS_PANEL_1", - template: "protections_panel", - content: { - title: { - string_id: "cfr-protections-panel-header" - }, - body: { - string_id: "cfr-protections-panel-body" - }, - link_text: { - string_id: "cfr-protections-panel-link-text" - }, - cta_url: "https://support.mozilla.org/1/firefox/121.0a1/Darwin/en-US/etp-promotions?as=u&utm_source=inproduct", - cta_type: "OPEN_URL" - }, - trigger: { - id: "protectionsPanelOpen" - }, - groups: [], - provider: "onboarding" -} -``` - -### A Bundled Message example -The following 2 messages have a `bundled` property, indicating that they should be shown together, since they have the same template. The number `2` indicates that this message should be shown in a bundle of 2 messages of the same template. The order property defines that ONBOARDING_2 should be shown after ONBOARDING_3 in the bundle. -```javascript -{ - id: "ONBOARDING_2", - template: "onboarding", - bundled: 2, - order: 2, - content: { - title: "Private Browsing", - body: "Browse by yourself. Private Browsing with Tracking Protection blocks online trackers that follow you around the web." - }, - targeting: "", - trigger: "firstRun" -} -{ - id: "ONBOARDING_3", - template: "onboarding", - bundled: 2, - order: 1, - content: { - title: "Find it faster", - body: "Access all of your favorite search engines with a click. Search the whole Web or just one website from the search box." - }, - targeting: "", - trigger: "firstRun" -} -``` - -### HTML subset -The following tags are allowed in the content of a message: `i, b, u, strong, em, br`. - -Links cannot be rendered using regular anchor tags because [Fluent does not allow for href attributes](https://github.com/projectfluent/fluent.js/blob/a03d3aa833660f8c620738b26c80e46b1a4edb05/fluent-dom/src/overlay.js#L13). They will be wrapped in custom tags, for example `link` and the url will be provided as part of the payload: -``` -{ - "id": "7899", - "content": { - "text": "Use the CMD (CTRL) + T keyboard shortcut to open a new tab quickly!", - "links": { - "cta": { - "url": "https://support.mozilla.org/en-US/kb/keyboard-shortcuts-perform-firefox-tasks-quickly" - } - } - } -} -``` -If a tag that is not on the allowed is used, the text content will be extracted and displayed. - -Grouping multiple allowed elements is not possible, only the first level will be used: `text` will be interpreted as `text`. - -### Trigger params -A set of hostnames that need to exactly match the location of the selected tab in order for the trigger to execute. -``` -["github.com", "wwww.github.com"] -``` -More examples in the [CFRMessageProvider](https://github.com/mozilla/activity-stream/blob/e76ce12fbaaac1182aa492b84fc038f78c3acc33/lib/CFRMessageProvider.jsm#L40-L47). - -### Trigger patterns -A set of patterns that can match multiple hostnames. When the location of the selected tab matches one of the patterns it can execute a trigger. -``` -["*://*.github.com"] // can match `github.com` but also match `https://gist.github.com/` -``` -More [MatchPattern examples](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns#Examples). - -### Targeting attributes -(This section has moved to [targeting-attributes.md](../docs/targeting-attributes.md)). diff --git a/browser/components/asrouter/content-src/styles/_shopping.scss b/browser/components/asrouter/content-src/styles/_shopping.scss index 218e996cb8..a13fbc8a74 100644 --- a/browser/components/asrouter/content-src/styles/_shopping.scss +++ b/browser/components/asrouter/content-src/styles/_shopping.scss @@ -85,6 +85,7 @@ margin-block: 0 20px; padding-inline: 30px; text-align: start; + color: inherit; a { text-decoration: underline; diff --git a/browser/components/asrouter/content-src/templates/OnboardingMessage/Spotlight.schema.json b/browser/components/asrouter/content-src/templates/OnboardingMessage/Spotlight.schema.json index 5d5b98f594..581f84dcc8 100644 --- a/browser/components/asrouter/content-src/templates/OnboardingMessage/Spotlight.schema.json +++ b/browser/components/asrouter/content-src/templates/OnboardingMessage/Spotlight.schema.json @@ -51,6 +51,10 @@ "startScreen": { "type": "integer", "description": "Index of first screen to show from message, defaulting to 0" + }, + "no-rdm": { + "type": "boolean", + "description": "If true, prevents the spotlight from entering responsive design mode at widths less than 800px" } }, "additionalProperties": true -- cgit v1.2.3