Bug 1877196 - Move FeatureCallout modules and styles to browser/components/asrouter. r=fxview-reviewers,omc-reviewers,sclements,aminomancer

Differential Revision: https://phabricator.services.mozilla.com/D200514
This commit is contained in:
Mike Conley 2024-02-05 22:03:16 +00:00
parent c65fe995c1
commit c8b2bacff2
23 changed files with 244 additions and 232 deletions

View File

@ -3,8 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@use 'sass:math';
@import 'chrome://global/skin/design-system/tokens-brand.css';
@import '../../newtab/content-src/styles/feature-callout';
@import '../../newtab/content-src/styles/shopping';
@import '../../asrouter/content-src/styles/feature-callout';
@import '../../asrouter/content-src/styles/shopping';
/* stylelint-disable max-nesting-depth */

View File

@ -37,7 +37,7 @@ The callout's arrow (the triangle-shaped caret pointing to the anchor) can be po
### Via local provider:
You can also test Feature Callouts by adding them to the [local provider](https://searchfox.org/mozilla-central/source/browser/components/newtab/lib/FeatureCalloutMessages.sys.mjs). While slower than using the devtools, this is useful when you want to test the trigger or targeting, or when your callout's anchor is an element that is not visible while on `about:asrouter` (such as a urlbar button).
You can also test Feature Callouts by adding them to the [local provider](https://searchfox.org/mozilla-central/source/browser/components/asrouter/modules/FeatureCalloutMessages.sys.mjs). While slower than using the devtools, this is useful when you want to test the trigger or targeting, or when your callout's anchor is an element that is not visible while on `about:asrouter` (such as a urlbar button).
### Via Experiments:

View File

@ -16,7 +16,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
Downloader: "resource://services-settings/Attachments.sys.mjs",
ExperimentAPI: "resource://nimbus/ExperimentAPI.sys.mjs",
FeatureCalloutBroker:
"resource://activity-stream/lib/FeatureCalloutBroker.sys.mjs",
"resource:///modules/asrouter/FeatureCalloutBroker.sys.mjs",
InfoBar: "resource:///modules/asrouter/InfoBar.sys.mjs",
KintoHttpClient: "resource://services-common/kinto-http-client.sys.mjs",
MacAttribution: "resource:///modules/MacAttribution.sys.mjs",

View File

@ -10,7 +10,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
BrowserUtils: "resource://gre/modules/BrowserUtils.sys.mjs",
EveryWindow: "resource:///modules/EveryWindow.sys.mjs",
FeatureCalloutBroker:
"resource://activity-stream/lib/FeatureCalloutBroker.sys.mjs",
"resource:///modules/asrouter/FeatureCalloutBroker.sys.mjs",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
clearTimeout: "resource://gre/modules/Timer.sys.mjs",
setTimeout: "resource://gre/modules/Timer.sys.mjs",

View File

@ -201,7 +201,7 @@ export class FeatureCallout {
}
}
async _maybeAdvanceScreens() {
_maybeAdvanceScreens() {
if (this.doc.visibilityState === "hidden" || !this.featureTourProgress) {
return;
}
@ -213,7 +213,7 @@ export class FeatureCallout {
// the next message in the tour.
if (
this.config?.screens.length === 1 ||
this.currentScreen == "spotlight"
this.currentScreen === "spotlight"
) {
this.showFeatureCallout();
return;
@ -407,7 +407,7 @@ export class FeatureCallout {
this.win.MozXULElement.insertFTLIfNeeded(path);
}
const addChromeSheet = async href => {
const addChromeSheet = href => {
try {
this.win.windowUtils.loadSheetUsingURIString(
href,
@ -623,7 +623,7 @@ export class FeatureCallout {
if (
this.context === "chrome" &&
element.id &&
anchor.selector.includes("#" + element.id)
anchor.selector.includes(`#${element.id}`)
) {
let widget = lazy.CustomizableUI.getWidget(element.id);
if (
@ -714,15 +714,15 @@ export class FeatureCallout {
case "end": {
// Inline arrow, i.e. arrow is on one of the left/right edges.
let isRTL =
this.ownerGlobal.getComputedStyle(this).direction == "rtl";
let isRight = isRTL ^ (positionParts[1] == "start");
this.ownerGlobal.getComputedStyle(this).direction === "rtl";
let isRight = isRTL ^ (positionParts[1] === "start");
let side = isRight ? "end" : "start";
arrowPosition = `inline-${side}`;
if (popupAlignment?.includes("center")) {
arrowPosition = `inline-${side}`;
} else if (positionParts[2] == "before") {
} else if (positionParts[2] === "before") {
arrowPosition = `inline-${side}-top`;
} else if (positionParts[2] == "after") {
} else if (positionParts[2] === "after") {
arrowPosition = `inline-${side}-bottom`;
}
break;
@ -730,13 +730,13 @@ export class FeatureCallout {
case "before":
case "after": {
// Block arrow, i.e. arrow is on one of the top/bottom edges.
let side = positionParts[1] == "before" ? "bottom" : "top";
let side = positionParts[1] === "before" ? "bottom" : "top";
arrowPosition = side;
if (popupAlignment?.includes("center")) {
arrowPosition = side;
} else if (positionParts[2] == "end") {
} else if (positionParts[2] === "end") {
arrowPosition = `${side}-end`;
} else if (positionParts[2] == "start") {
} else if (positionParts[2] === "start") {
arrowPosition = `${side}-start`;
}
break;
@ -859,7 +859,7 @@ export class FeatureCallout {
return;
}
const parentEl = anchor.element;
const doc = this.doc;
const { doc } = this;
const arrowPosition = anchor.arrow_position || "top";
const arrowWidth = anchor.arrow_width || 33.94113;
const arrowHeight = arrowWidth / 2;
@ -879,103 +879,77 @@ export class FeatureCallout {
};
};
const clearPosition = () => {
Object.keys(positioners).forEach(position => {
container.style[position] = "unset";
});
container.removeAttribute("arrow-position");
const centerVertically = () => {
let topOffset =
(container.getBoundingClientRect().height -
parentEl.getBoundingClientRect().height) /
2;
container.style.top = `${getOffset(parentEl).top - topOffset}px`;
};
const setArrowPosition = position => {
let val;
/**
* Horizontally align a top/bottom-positioned callout according to the
* passed position.
* @param {String} position one of...
* - "center": for use with top/bottom. arrow is in the center, and the
* center of the callout aligns with the parent center.
* - "center-arrow-start": for use with center-arrow-top-start. arrow is
* on the start (left) side of the callout, and the callout is aligned
* so that the arrow points to the center of the parent element.
* - "center-arrow-end": for use with center-arrow-top-end. arrow is on
* the end, and the arrow points to the center of the parent.
* - "start": currently unused. align the callout's starting edge with the
* parent's starting edge.
* - "end": currently unused. same as start but for the ending edge.
*/
const alignHorizontally = position => {
switch (position) {
case "bottom":
val = "bottom";
case "center": {
const sideOffset =
(parentEl.getBoundingClientRect().width -
container.getBoundingClientRect().width) /
2;
const containerSide = RTL
? doc.documentElement.clientWidth -
getOffset(parentEl).right +
sideOffset
: getOffset(parentEl).left + sideOffset;
container.style[RTL ? "right" : "left"] = `${Math.max(
containerSide,
0
)}px`;
break;
case "left":
val = "inline-start";
break;
case "right":
val = "inline-end";
break;
case "top-start":
case "top-center-arrow-start":
val = RTL ? "top-end" : "top-start";
break;
case "top-end":
case "top-center-arrow-end":
val = RTL ? "top-start" : "top-end";
break;
case "top":
default:
val = "top";
break;
}
container.setAttribute("arrow-position", val);
};
const addValueToPixelValue = (value, pixelValue) => {
return `${parseFloat(pixelValue) + value}px`;
};
const subtractPixelValueFromValue = (pixelValue, value) => {
return `${value - parseFloat(pixelValue)}px`;
};
const overridePosition = () => {
// We override _every_ positioner here, because we want to manually set
// all container.style.positions in every positioner's "position" function
// regardless of the actual arrow position
// Note: We override the position functions with new functions here, but
// they don't actually get executed until the respective position
// functions are called and this function is not executed unless the
// message has a custom position property.
// We're positioning relative to a parent element's bounds, if that parent
// element exists.
for (const position in positioners) {
positioners[position].position = () => {
if (customPosition.top) {
container.style.top = addValueToPixelValue(
parentEl.getBoundingClientRect().top,
customPosition.top
);
}
if (customPosition.left) {
const leftPosition = addValueToPixelValue(
parentEl.getBoundingClientRect().left,
customPosition.left
);
RTL
? (container.style.right = leftPosition)
: (container.style.left = leftPosition);
}
if (customPosition.right) {
const rightPosition = subtractPixelValueFromValue(
customPosition.right,
parentEl.getBoundingClientRect().right -
}
case "end":
case "start": {
const containerSide =
RTL ^ (position === "end")
? parentEl.getBoundingClientRect().left +
parentEl.getBoundingClientRect().width -
container.getBoundingClientRect().width
);
RTL
? (container.style.right = rightPosition)
: (container.style.left = rightPosition);
}
if (customPosition.bottom) {
container.style.top = subtractPixelValueFromValue(
customPosition.bottom,
parentEl.getBoundingClientRect().bottom -
container.getBoundingClientRect().height
);
}
};
: parentEl.getBoundingClientRect().left;
container.style.left = `${Math.max(containerSide, 0)}px`;
break;
}
case "center-arrow-end":
case "center-arrow-start": {
const parentRect = parentEl.getBoundingClientRect();
const containerWidth = container.getBoundingClientRect().width;
const containerSide =
RTL ^ position.endsWith("end")
? parentRect.left +
parentRect.width / 2 +
12 +
arrowWidth / 2 -
containerWidth
: parentRect.left + parentRect.width / 2 - 12 - arrowWidth / 2;
const maxContainerSide =
doc.documentElement.clientWidth - containerWidth;
container.style.left = `${Math.min(
maxContainerSide,
Math.max(containerSide, 0)
)}px`;
}
}
};
@ -1144,13 +1118,121 @@ export class FeatureCallout {
},
};
const clearPosition = () => {
Object.keys(positioners).forEach(position => {
container.style[position] = "unset";
});
container.removeAttribute("arrow-position");
};
const setArrowPosition = position => {
let val;
switch (position) {
case "bottom":
val = "bottom";
break;
case "left":
val = "inline-start";
break;
case "right":
val = "inline-end";
break;
case "top-start":
case "top-center-arrow-start":
val = RTL ? "top-end" : "top-start";
break;
case "top-end":
case "top-center-arrow-end":
val = RTL ? "top-start" : "top-end";
break;
case "top":
default:
val = "top";
break;
}
container.setAttribute("arrow-position", val);
};
const addValueToPixelValue = (value, pixelValue) => {
return `${parseFloat(pixelValue) + value}px`;
};
const subtractPixelValueFromValue = (pixelValue, value) => {
return `${value - parseFloat(pixelValue)}px`;
};
const overridePosition = () => {
// We override _every_ positioner here, because we want to manually set
// all container.style.positions in every positioner's "position" function
// regardless of the actual arrow position
// Note: We override the position functions with new functions here, but
// they don't actually get executed until the respective position
// functions are called and this function is not executed unless the
// message has a custom position property.
// We're positioning relative to a parent element's bounds, if that parent
// element exists.
for (const position in positioners) {
if (!Object.prototype.hasOwnProperty.call(positioners, position)) {
continue;
}
positioners[position].position = () => {
if (customPosition.top) {
container.style.top = addValueToPixelValue(
parentEl.getBoundingClientRect().top,
customPosition.top
);
}
if (customPosition.left) {
const leftPosition = addValueToPixelValue(
parentEl.getBoundingClientRect().left,
customPosition.left
);
if (RTL) {
container.style.right = leftPosition;
} else {
container.style.left = leftPosition;
}
}
if (customPosition.right) {
const rightPosition = subtractPixelValueFromValue(
customPosition.right,
parentEl.getBoundingClientRect().right -
container.getBoundingClientRect().width
);
if (RTL) {
container.style.right = rightPosition;
} else {
container.style.left = rightPosition;
}
}
if (customPosition.bottom) {
container.style.top = subtractPixelValueFromValue(
customPosition.bottom,
parentEl.getBoundingClientRect().bottom -
container.getBoundingClientRect().height
);
}
};
}
};
const calloutFits = position => {
// Does callout element fit in this position relative
// to the parent element without going off screen?
// Only consider which edge of the callout the arrow points from,
// not the alignment of the arrow along the edge of the callout
let edgePosition = position.split("-")[0];
let [edgePosition] = position.split("-");
return (
positioners[edgePosition].availableSpace() >
positioners[edgePosition].neededSpace
@ -1190,80 +1272,6 @@ export class FeatureCallout {
return sortedPositions[0] || position;
};
const centerVertically = () => {
let topOffset =
(container.getBoundingClientRect().height -
parentEl.getBoundingClientRect().height) /
2;
container.style.top = `${getOffset(parentEl).top - topOffset}px`;
};
/**
* Horizontally align a top/bottom-positioned callout according to the
* passed position.
* @param {String} position one of...
* - "center": for use with top/bottom. arrow is in the center, and the
* center of the callout aligns with the parent center.
* - "center-arrow-start": for use with center-arrow-top-start. arrow is
* on the start (left) side of the callout, and the callout is aligned
* so that the arrow points to the center of the parent element.
* - "center-arrow-end": for use with center-arrow-top-end. arrow is on
* the end, and the arrow points to the center of the parent.
* - "start": currently unused. align the callout's starting edge with the
* parent's starting edge.
* - "end": currently unused. same as start but for the ending edge.
*/
const alignHorizontally = position => {
switch (position) {
case "center": {
const sideOffset =
(parentEl.getBoundingClientRect().width -
container.getBoundingClientRect().width) /
2;
const containerSide = RTL
? doc.documentElement.clientWidth -
getOffset(parentEl).right +
sideOffset
: getOffset(parentEl).left + sideOffset;
container.style[RTL ? "right" : "left"] = `${Math.max(
containerSide,
0
)}px`;
break;
}
case "end":
case "start": {
const containerSide =
RTL ^ (position === "end")
? parentEl.getBoundingClientRect().left +
parentEl.getBoundingClientRect().width -
container.getBoundingClientRect().width
: parentEl.getBoundingClientRect().left;
container.style.left = `${Math.max(containerSide, 0)}px`;
break;
}
case "center-arrow-end":
case "center-arrow-start": {
const parentRect = parentEl.getBoundingClientRect();
const containerWidth = container.getBoundingClientRect().width;
const containerSide =
RTL ^ position.endsWith("end")
? parentRect.left +
parentRect.width / 2 +
12 +
arrowWidth / 2 -
containerWidth
: parentRect.left + parentRect.width / 2 - 12 - arrowWidth / 2;
const maxContainerSide =
doc.documentElement.clientWidth - containerWidth;
container.style.left = `${Math.min(
maxContainerSide,
Math.max(containerSide, 0)
)}px`;
}
}
};
clearPosition(container);
if (customPosition) {
@ -1407,7 +1415,7 @@ export class FeatureCallout {
const reactSrc = "resource://activity-stream/vendor/react.js";
const domSrc = "resource://activity-stream/vendor/react-dom.js";
// Add React script
const getReactReady = async () => {
const getReactReady = () => {
return new Promise(resolve => {
let reactScript = this.doc.createElement("script");
reactScript.src = reactSrc;
@ -1416,7 +1424,7 @@ export class FeatureCallout {
});
};
// Add ReactDom script
const getDomReady = async () => {
const getDomReady = () => {
return new Promise(resolve => {
let domScript = this.doc.createElement("script");
domScript.src = domSrc;
@ -1529,7 +1537,7 @@ export class FeatureCallout {
if (container) {
// This results in rendering the Feature Callout
await this._addScriptsAndRender();
this._observeRender(container.querySelector("#" + CONTENT_BOX_ID));
this._observeRender(container.querySelector(`#${CONTENT_BOX_ID}`));
if (container.localName === "div") {
this._addPositionListeners();
}

View File

@ -5,7 +5,7 @@
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
FeatureCallout: "resource:///modules/FeatureCallout.sys.mjs",
FeatureCallout: "resource:///modules/asrouter/FeatureCallout.sys.mjs",
});
/**
@ -28,7 +28,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
* @property {FeatureCalloutTheme} [theme] optional dynamic color theme.
*/
/** @typedef {import("resource:///modules/FeatureCallout.sys.mjs").FeatureCalloutTheme} FeatureCalloutTheme */
/** @typedef {import("resource:///modules/asrouter/FeatureCallout.sys.mjs").FeatureCalloutTheme} FeatureCalloutTheme */
/**
* @typedef {Object} FeatureCalloutItem

View File

@ -10,7 +10,7 @@ const { AppConstants } = ChromeUtils.importESModule(
"resource://gre/modules/AppConstants.sys.mjs"
);
const { FeatureCalloutMessages } = ChromeUtils.importESModule(
"resource://activity-stream/lib/FeatureCalloutMessages.sys.mjs"
"resource:///modules/asrouter/FeatureCalloutMessages.sys.mjs"
);
const lazy = {};

View File

@ -25,6 +25,9 @@ EXTRA_JS_MODULES.asrouter += [
"modules/ASRouterTriggerListeners.jsm",
"modules/CFRMessageProvider.sys.mjs",
"modules/CFRPageActions.jsm",
"modules/FeatureCallout.sys.mjs",
"modules/FeatureCalloutBroker.sys.mjs",
"modules/FeatureCalloutMessages.sys.mjs",
"modules/InfoBar.sys.mjs",
"modules/MessagingExperimentConstants.sys.mjs",
"modules/MomentsPageHub.sys.mjs",

View File

@ -32,5 +32,13 @@ tags = "remote-settings"
tags = "remote-settings"
skip-if = ["a11y_checks"] # Bug 1854515 and 1858041 to investigate intermittent a11y_checks results (fails on Autoland, passes on Try)
["browser_feature_callout_in_chrome.js"]
skip-if = [
"os == 'mac' && debug", # Bug 1804349
"win11_2009", # Bug 1804349
]
["browser_feature_callout_panel.js"]
["browser_trigger_listeners.js"]
https_first_disabled = true

View File

@ -1,6 +1,11 @@
"use strict";
ChromeUtils.defineESModuleGetters(this, {
FeatureCallout: "resource:///modules/asrouter/FeatureCallout.sys.mjs",
FeatureCalloutBroker:
"resource:///modules/asrouter/FeatureCalloutBroker.sys.mjs",
FeatureCalloutMessages:
"resource:///modules/asrouter/FeatureCalloutMessages.sys.mjs",
PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
});
XPCOMUtils.defineLazyModuleGetters(this, {
@ -15,6 +20,12 @@ const { sinon } = ChromeUtils.importESModule(
"resource://testing-common/Sinon.sys.mjs"
);
// Feature callout constants
const calloutId = "feature-callout";
const calloutSelector = `#${calloutId}.featureCallout`;
const calloutCTASelector = `#${calloutId} :is(.primary, .secondary)`;
const calloutDismissSelector = `#${calloutId} .dismiss-button`;
function pushPrefs(...prefs) {
return SpecialPowers.pushPrefEnv({ set: prefs });
}
@ -34,3 +45,19 @@ async function waitForUrlLoad(url) {
BrowserTestUtils.startLoadingURIString(browser, url);
await BrowserTestUtils.browserLoaded(browser, false, url);
}
async function waitForCalloutScreen(target, screenId) {
await BrowserTestUtils.waitForMutationCondition(
target,
{ childList: true, subtree: true, attributeFilter: ["class"] },
() => target.querySelector(`${calloutSelector}:not(.hidden) .${screenId}`)
);
}
async function waitForCalloutRemoved(target) {
await BrowserTestUtils.waitForMutationCondition(
target,
{ childList: true, subtree: true },
() => !target.querySelector(calloutSelector)
);
}

View File

@ -4,7 +4,7 @@
"use strict";
const { FeatureCallout } = ChromeUtils.importESModule(
"resource:///modules/FeatureCallout.sys.mjs"
"resource:///modules/asrouter/FeatureCallout.sys.mjs"
);
async function testCallout(config) {

View File

@ -26,7 +26,7 @@ const { sinon } = ChromeUtils.importESModule(
"resource://testing-common/Sinon.sys.mjs"
);
const { FeatureCalloutMessages } = ChromeUtils.importESModule(
"resource://activity-stream/lib/FeatureCalloutMessages.sys.mjs"
"resource:///modules/asrouter/FeatureCalloutMessages.sys.mjs"
);
const { TelemetryTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/TelemetryTestUtils.sys.mjs"
@ -334,7 +334,7 @@ async function tearDown(sandbox) {
const featureTourPref = "browser.firefox-view.feature-tour";
const launchFeatureTourIn = win => {
const { FeatureCallout } = ChromeUtils.importESModule(
"resource:///modules/FeatureCallout.sys.mjs"
"resource:///modules/asrouter/FeatureCallout.sys.mjs"
);
let callout = new FeatureCallout({
win,

View File

@ -10,7 +10,7 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
FeatureCalloutBroker:
"resource://activity-stream/lib/FeatureCalloutBroker.sys.mjs",
"resource:///modules/asrouter/FeatureCalloutBroker.sys.mjs",
InfoBar: "resource:///modules/asrouter/InfoBar.sys.mjs",
SpecialMessageActions:
"resource://messaging-system/lib/SpecialMessageActions.sys.mjs",

View File

@ -38,14 +38,6 @@ https_first_disabled = true
["browser_enabled_newtabpage.js"]
["browser_feature_callout_in_chrome.js"]
skip-if = [
"os == 'mac' && debug", # Bug 1804349
"win11_2009", # Bug 1804349
]
["browser_feature_callout_panel.js"]
["browser_foxdoodle_set_default.js"]
["browser_getScreenshots.js"]

View File

@ -3,11 +3,11 @@
ChromeUtils.defineESModuleGetters(this, {
DiscoveryStreamFeed:
"resource://activity-stream/lib/DiscoveryStreamFeed.sys.mjs",
FeatureCallout: "resource:///modules/FeatureCallout.sys.mjs",
FeatureCallout: "resource:///modules/asrouter/FeatureCallout.sys.mjs",
FeatureCalloutBroker:
"resource://activity-stream/lib/FeatureCalloutBroker.sys.mjs",
"resource:///modules/asrouter/FeatureCalloutBroker.sys.mjs",
FeatureCalloutMessages:
"resource://activity-stream/lib/FeatureCalloutMessages.sys.mjs",
"resource:///modules/asrouter/FeatureCalloutMessages.sys.mjs",
ObjectUtils: "resource://gre/modules/ObjectUtils.sys.mjs",
PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
});
@ -21,12 +21,6 @@ const { sinon } = ChromeUtils.importESModule(
"resource://testing-common/Sinon.sys.mjs"
);
// Feature callout constants
const calloutId = "feature-callout";
const calloutSelector = `#${calloutId}.featureCallout`;
const calloutCTASelector = `#${calloutId} :is(.primary, .secondary)`;
const calloutDismissSelector = `#${calloutId} .dismiss-button`;
function popPrefs() {
return SpecialPowers.popPrefEnv();
}
@ -245,19 +239,3 @@ function test_newtab(testInfo, browserURL = "about:newtab") {
Object.defineProperty(testTask, "name", { value: contentTask.name });
add_task(testTask);
}
async function waitForCalloutScreen(target, screenId) {
await BrowserTestUtils.waitForMutationCondition(
target,
{ childList: true, subtree: true, attributeFilter: ["class"] },
() => target.querySelector(`${calloutSelector}:not(.hidden) .${screenId}`)
);
}
async function waitForCalloutRemoved(target) {
await BrowserTestUtils.waitForMutationCondition(
target,
{ childList: true, subtree: true },
() => !target.querySelector(calloutSelector)
);
}

View File

@ -12,7 +12,7 @@ const { ASRouter } = ChromeUtils.import(
);
const { FeatureCalloutMessages } = ChromeUtils.importESModule(
"resource://activity-stream/lib/FeatureCalloutMessages.sys.mjs"
"resource:///modules/asrouter/FeatureCalloutMessages.sys.mjs"
);
const OPTED_IN_PREF = "browser.shopping.experience2023.optedIn";

View File

@ -61,9 +61,6 @@ with Files("EveryWindow.sys.mjs"):
with Files("ExtensionsUI.sys.mjs"):
BUG_COMPONENT = ("WebExtensions", "General")
with Files("FeatureCallout.sys.mjs"):
BUG_COMPONENT = ("Firefox", "Messaging System")
with Files("LaterRun.sys.mjs"):
BUG_COMPONENT = ("Firefox", "Tours")
@ -131,7 +128,6 @@ EXTRA_JS_MODULES += [
"EveryWindow.sys.mjs",
"ExtensionsUI.sys.mjs",
"FaviconLoader.sys.mjs",
"FeatureCallout.sys.mjs",
"HomePage.sys.mjs",
"LaterRun.sys.mjs",
"NewTabPagePreloading.sys.mjs",