diff options
Diffstat (limited to 'browser/components/asrouter/content-src')
-rw-r--r-- | browser/components/asrouter/content-src/asrouter-utils.mjs (renamed from browser/components/asrouter/content-src/asrouter-utils.js) | 18 | ||||
-rw-r--r-- | browser/components/asrouter/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx | 25 | ||||
-rw-r--r-- | browser/components/asrouter/content-src/components/ASRouterAdmin/CopyButton.jsx | 2 | ||||
-rw-r--r-- | browser/components/asrouter/content-src/components/ConditionalWrapper/ConditionalWrapper.jsx | 9 | ||||
-rw-r--r-- | browser/components/asrouter/content-src/components/ImpressionsWrapper/ImpressionsWrapper.jsx | 76 | ||||
-rw-r--r-- | browser/components/asrouter/content-src/schemas/MessagingExperiment.schema.json | 4 | ||||
-rw-r--r-- | browser/components/asrouter/content-src/schemas/message-format.md | 111 | ||||
-rw-r--r-- | browser/components/asrouter/content-src/styles/_shopping.scss | 1 | ||||
-rw-r--r-- | browser/components/asrouter/content-src/templates/OnboardingMessage/Spotlight.schema.json | 4 |
9 files changed, 31 insertions, 219 deletions
diff --git a/browser/components/asrouter/content-src/asrouter-utils.js b/browser/components/asrouter/content-src/asrouter-utils.mjs index 65d25cb907..989d864e71 100644 --- a/browser/components/asrouter/content-src/asrouter-utils.js +++ b/browser/components/asrouter/content-src/asrouter-utils.mjs @@ -2,23 +2,25 @@ * 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"; +// 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 (global.ASRouterAddParentListener) { - global.ASRouterAddParentListener(listener); + if (globalThis.ASRouterAddParentListener) { + globalThis.ASRouterAddParentListener(listener); } }, removeListener(listener) { - if (global.ASRouterRemoveParentListener) { - global.ASRouterRemoveParentListener(listener); + if (globalThis.ASRouterRemoveParentListener) { + globalThis.ASRouterRemoveParentListener(listener); } }, sendMessage(action) { - if (global.ASRouterMessage) { - return global.ASRouterMessage(action); + if (globalThis.ASRouterMessage) { + return globalThis.ASRouterMessage(action); } throw new Error(`Unexpected call:\n${JSON.stringify(action, null, 3)}`); }, 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 ? ( <button className="button restore" - onClick={e => this.resetJSON(msg)} + onClick={() => this.resetJSON(msg)} > Reset </button> @@ -523,7 +523,7 @@ export class ASRouterAdminInner extends React.PureComponent { {isBlocked ? null : ( <button className="button modify" - onClick={e => this.modifyJson(msg)} + onClick={() => this.modifyJson(msg)} > Modify </button> @@ -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)} </textarea> @@ -647,7 +647,7 @@ export class ASRouterAdminInner extends React.PureComponent { </button> <button className="ASRouterButton slim button" - onClick={e => this.resetPBJSON(msg)} + onClick={() => this.resetPBJSON(msg)} > Reset JSON </button> @@ -698,7 +698,7 @@ export class ASRouterAdminInner extends React.PureComponent { <div> <button className="ASRouterButton slim" - onClick={e => this.toggleAllMessages(messagesToShow)} + onClick={() => this.toggleAllMessages(messagesToShow)} > Collapse/Expand All </button> @@ -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 { <h2>Messages</h2> <button className="ASRouterButton slim button" - onClick={e => this.toggleAllMessages(messagesToShow)} + onClick={() => this.toggleAllMessages(messagesToShow)} > Collapse/Expand All </button> @@ -1359,10 +1359,7 @@ export class ASRouterAdminInner extends React.PureComponent { <tbody> {this.state.groups && this.state.groups.map( - ( - { id, enabled, frequency, userPreferences = [] }, - index - ) => ( + ({ id, enabled, frequency, userPreferences = [] }) => ( <Row key={id}> <td> <TogglePrefCheckbox @@ -1473,7 +1470,7 @@ export class ASRouterAdminInner extends React.PureComponent { Need help using these tools? Check out our{" "} <a target="blank" - href="https://firefox-source-docs.mozilla.org/browser/components/newtab/content-src/asrouter/docs/debugging-docs.html" + href="https://firefox-source-docs.mozilla.org/browser/components/asrouter/docs/debugging-docs.html" > documentation </a> 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 ( - <button className={className} onClick={e => onClick()} {...props}> + <button className={className} onClick={() => onClick()} {...props}> {(copied && copiedLabel) || label} </button> ); 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 `<cta>link</cta>` and the url will be provided as part of the payload: -``` -{ - "id": "7899", - "content": { - "text": "Use the CMD (CTRL) + T keyboard shortcut to <cta>open a new tab quickly!</cta>", - "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: `<u><b>text</b></u>` will be interpreted as `<u>text</u>`. - -### 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 |