Bug 1826360 - Do not include sponsored tiles for about:home startup cache r=mconley,thecount

Differential Revision: https://phabricator.services.mozilla.com/D174646
This commit is contained in:
Mike Conley 2023-04-04 18:25:43 +00:00
Родитель 177cdbd4d9
Коммит 77f968a1cb
4 изменённых файлов: 118 добавлений и 32 удалений

Просмотреть файл

@ -16,6 +16,7 @@ export const INITIAL_STATE = {
// Have we received real data from the app yet?
initialized: false,
locale: "",
isForStartupCache: false,
},
ASRouter: { initialized: false },
Snippets: { initialized: false },
@ -101,6 +102,12 @@ function App(prevState = INITIAL_STATE.App, action) {
return Object.assign({}, prevState, action.data || {}, {
initialized: true,
});
case at.TOP_SITES_UPDATED:
// Toggle `isForStartupCache` when receiving the `TOP_SITES_UPDATE` action
// so that sponsored tiles can be rendered as usual. See Bug 1826360.
return Object.assign({}, prevState, action.data || {}, {
isForStartupCache: false,
});
default:
return prevState;
}

Просмотреть файл

@ -22,6 +22,8 @@ import { ScreenshotUtils } from "content-src/lib/screenshot-utils";
import { TOP_SITES_MAX_SITES_PER_ROW } from "common/Reducers.sys.mjs";
import { ContextMenuButton } from "content-src/components/ContextMenu/ContextMenuButton";
import { TopSiteImpressionWrapper } from "./TopSiteImpressionWrapper";
import { connect } from "react-redux";
const SPOC_TYPE = "SPOC";
const NEWTAB_SOURCE = "newtab";
@ -640,7 +642,7 @@ export class TopSitePlaceholder extends React.PureComponent {
}
}
export class TopSiteList extends React.PureComponent {
export class _TopSiteList extends React.PureComponent {
static get DEFAULT_STATE() {
return {
activeIndex: null,
@ -653,7 +655,7 @@ export class TopSiteList extends React.PureComponent {
constructor(props) {
super(props);
this.state = TopSiteList.DEFAULT_STATE;
this.state = _TopSiteList.DEFAULT_STATE;
this.onDragEvent = this.onDragEvent.bind(this);
this.onActivate = this.onActivate.bind(this);
}
@ -672,7 +674,7 @@ export class TopSiteList extends React.PureComponent {
this.state.draggedSite.url)
) {
// We got the new order from the redux store via props. We can clear state now.
this.setState(TopSiteList.DEFAULT_STATE);
this.setState(_TopSiteList.DEFAULT_STATE);
}
}
}
@ -702,7 +704,7 @@ export class TopSiteList extends React.PureComponent {
case "dragend":
if (!this.dropped) {
// If there was no drop event, reset the state to the default.
this.setState(TopSiteList.DEFAULT_STATE);
this.setState(_TopSiteList.DEFAULT_STATE);
}
break;
case "dragenter":
@ -831,6 +833,7 @@ export class TopSiteList extends React.PureComponent {
Object.assign({}, topSites[i], {
iconType: this.props.topSiteIconType(topSites[i]),
});
const slotProps = {
key: link ? link.url : holeIndex++,
index: i,
@ -838,10 +841,14 @@ export class TopSiteList extends React.PureComponent {
if (i >= maxNarrowVisibleIndex) {
slotProps.className = "hide-for-narrow";
}
topSitesUI.push(
!link ? (
<TopSitePlaceholder {...slotProps} {...commonProps} />
) : (
let topSiteLink;
// Use a placeholder if the link is empty or it's rendering a sponsored
// tile for the about:home startup cache.
if (!link || (props.App.isForStartupCache && isSponsored(link))) {
topSiteLink = <TopSitePlaceholder {...slotProps} {...commonProps} />;
} else {
topSiteLink = (
<TopSite
link={link}
activeIndex={this.state.activeIndex}
@ -850,8 +857,10 @@ export class TopSiteList extends React.PureComponent {
{...commonProps}
colors={props.colors}
/>
)
);
);
}
topSitesUI.push(topSiteLink);
}
return (
<ul
@ -864,3 +873,7 @@ export class TopSiteList extends React.PureComponent {
);
}
}
export const TopSiteList = connect(state => ({
App: state.App,
}))(_TopSiteList);

Просмотреть файл

@ -10548,6 +10548,7 @@ const INITIAL_STATE = {
// Have we received real data from the app yet?
initialized: false,
locale: "",
isForStartupCache: false,
},
ASRouter: { initialized: false },
Snippets: { initialized: false },
@ -10633,6 +10634,12 @@ function App(prevState = INITIAL_STATE.App, action) {
return Object.assign({}, prevState, action.data || {}, {
initialized: true,
});
case actionTypes.TOP_SITES_UPDATED:
// Toggle `isForStartupCache` when receiving the `TOP_SITES_UPDATE` action
// so that sponsored tiles can be rendered as usual. See Bug 1826360.
return Object.assign({}, prevState, action.data || {}, {
isForStartupCache: false,
});
default:
return prevState;
}
@ -11640,6 +11647,7 @@ function TopSite_extends() { TopSite_extends = Object.assign || function (target
const SPOC_TYPE = "SPOC";
const NEWTAB_SOURCE = "newtab"; // For cases if we want to know if this is sponsored by either sponsored_position or type.
// We have two sources for sponsored topsites, and
@ -12234,7 +12242,7 @@ class TopSitePlaceholder extends (external_React_default()).PureComponent {
}
}
class TopSiteList extends (external_React_default()).PureComponent {
class _TopSiteList extends (external_React_default()).PureComponent {
static get DEFAULT_STATE() {
return {
activeIndex: null,
@ -12247,7 +12255,7 @@ class TopSiteList extends (external_React_default()).PureComponent {
constructor(props) {
super(props);
this.state = TopSiteList.DEFAULT_STATE;
this.state = _TopSiteList.DEFAULT_STATE;
this.onDragEvent = this.onDragEvent.bind(this);
this.onActivate = this.onActivate.bind(this);
}
@ -12259,7 +12267,7 @@ class TopSiteList extends (external_React_default()).PureComponent {
if (prevTopSites && prevTopSites[this.state.draggedIndex] && prevTopSites[this.state.draggedIndex].url === this.state.draggedSite.url && (!newTopSites[this.state.draggedIndex] || newTopSites[this.state.draggedIndex].url !== this.state.draggedSite.url)) {
// We got the new order from the redux store via props. We can clear state now.
this.setState(TopSiteList.DEFAULT_STATE);
this.setState(_TopSiteList.DEFAULT_STATE);
}
}
}
@ -12288,7 +12296,7 @@ class TopSiteList extends (external_React_default()).PureComponent {
case "dragend":
if (!this.dropped) {
// If there was no drop event, reset the state to the default.
this.setState(TopSiteList.DEFAULT_STATE);
this.setState(_TopSiteList.DEFAULT_STATE);
}
break;
@ -12434,13 +12442,22 @@ class TopSiteList extends (external_React_default()).PureComponent {
slotProps.className = "hide-for-narrow";
}
topSitesUI.push(!link ? /*#__PURE__*/external_React_default().createElement(TopSitePlaceholder, TopSite_extends({}, slotProps, commonProps)) : /*#__PURE__*/external_React_default().createElement(TopSite, TopSite_extends({
link: link,
activeIndex: this.state.activeIndex,
onActivate: this.onActivate
}, slotProps, commonProps, {
colors: props.colors
})));
let topSiteLink; // Use a placeholder if the link is empty or it's rendering a sponsored
// tile for the about:home startup cache.
if (!link || props.App.isForStartupCache && isSponsored(link)) {
topSiteLink = /*#__PURE__*/external_React_default().createElement(TopSitePlaceholder, TopSite_extends({}, slotProps, commonProps));
} else {
topSiteLink = /*#__PURE__*/external_React_default().createElement(TopSite, TopSite_extends({
link: link,
activeIndex: this.state.activeIndex,
onActivate: this.onActivate
}, slotProps, commonProps, {
colors: props.colors
}));
}
topSitesUI.push(topSiteLink);
}
return /*#__PURE__*/external_React_default().createElement("ul", {
@ -12449,6 +12466,9 @@ class TopSiteList extends (external_React_default()).PureComponent {
}
}
const TopSiteList = (0,external_ReactRedux_namespaceObject.connect)(state => ({
App: state.App
}))(_TopSiteList);
;// CONCATENATED MODULE: ./content-src/components/TopSites/TopSiteForm.jsx
/* 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,

Просмотреть файл

@ -11,7 +11,7 @@ import {
import {
TopSite,
TopSiteLink,
TopSiteList,
_TopSiteList as TopSiteList,
TopSitePlaceholder,
} from "content-src/components/TopSites/TopSite";
import {
@ -1443,14 +1443,16 @@ describe("<TopSiteForm>", () => {
});
describe("<TopSiteList>", () => {
const APP = { isForStartupCache: false };
it("should render a TopSiteList element", () => {
const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} />);
const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} App={{ APP }} />);
assert.ok(wrapper.exists());
});
it("should render a TopSite for each link with the right url", () => {
const rows = [{ url: "https://foo.com" }, { url: "https://bar.com" }];
const wrapper = shallow(
<TopSiteList {...DEFAULT_PROPS} TopSites={{ rows }} />
<TopSiteList {...DEFAULT_PROPS} TopSites={{ rows }} App={{ APP }} />
);
const links = wrapper.find(TopSite);
assert.lengthOf(links, 2);
@ -1472,6 +1474,7 @@ describe("<TopSiteList>", () => {
{...DEFAULT_PROPS}
TopSites={{ rows }}
TopSitesRows={TOP_SITES_DEFAULT_ROWS}
App={{ APP }}
/>
);
const links = wrapper.find(TopSite);
@ -1483,7 +1486,35 @@ describe("<TopSiteList>", () => {
it("should fill with placeholders if TopSites rows is less than TopSitesRows", () => {
const rows = [{ url: "https://foo.com" }, { url: "https://bar.com" }];
const wrapper = shallow(
<TopSiteList {...DEFAULT_PROPS} TopSites={{ rows }} TopSitesRows={1} />
<TopSiteList
{...DEFAULT_PROPS}
TopSites={{ rows }}
TopSitesRows={1}
App={{ APP }}
/>
);
assert.lengthOf(wrapper.find(TopSite), 2, "topSites");
assert.lengthOf(
wrapper.find(TopSitePlaceholder),
TOP_SITES_MAX_SITES_PER_ROW - 2,
"placeholders"
);
});
it("should fill sponsored top sites with placeholders while rendering for startup cache", () => {
const rows = [
{ url: "https://sponsored01.com", sponsored_position: 1 },
{ url: "https://sponsored02.com", sponsored_position: 2 },
{ url: "https://sponsored03.com", type: "SPOC" },
{ url: "https://foo.com" },
{ url: "https://bar.com" },
];
const wrapper = shallow(
<TopSiteList
{...DEFAULT_PROPS}
TopSites={{ rows }}
TopSitesRows={1}
App={{ isForStartupCache: true }}
/>
);
assert.lengthOf(wrapper.find(TopSite), 2, "topSites");
assert.lengthOf(
@ -1496,7 +1527,12 @@ describe("<TopSiteList>", () => {
const rows = [{ url: "https://foo.com" }];
rows[3] = { url: "https://bar.com" };
const wrapper = shallow(
<TopSiteList {...DEFAULT_PROPS} TopSites={{ rows }} TopSitesRows={1} />
<TopSiteList
{...DEFAULT_PROPS}
TopSites={{ rows }}
TopSitesRows={1}
App={{ APP }}
/>
);
assert.lengthOf(wrapper.find(TopSite), 2, "topSites");
assert.lengthOf(
@ -1506,7 +1542,7 @@ describe("<TopSiteList>", () => {
);
});
it("should update state onDragStart and clear it onDragEnd", () => {
const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} />);
const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} App={{ APP }} />);
const instance = wrapper.instance();
const index = 7;
const link = { url: "https://foo.com" };
@ -1523,7 +1559,7 @@ describe("<TopSiteList>", () => {
const site2 = { url: "https://bar.com" };
const rows = [site1, site2];
const wrapper = shallow(
<TopSiteList {...DEFAULT_PROPS} TopSites={{ rows }} />
<TopSiteList {...DEFAULT_PROPS} TopSites={{ rows }} App={{ APP }} />
);
const instance = wrapper.instance();
instance.setState({
@ -1538,7 +1574,7 @@ describe("<TopSiteList>", () => {
it("should dispatch events on drop", () => {
const dispatch = sinon.spy();
const wrapper = shallow(
<TopSiteList {...DEFAULT_PROPS} dispatch={dispatch} />
<TopSiteList {...DEFAULT_PROPS} dispatch={dispatch} App={{ APP }} />
);
const instance = wrapper.instance();
const index = 7;
@ -1568,7 +1604,7 @@ describe("<TopSiteList>", () => {
});
});
it("should make a topSitesPreview onDragEnter", () => {
const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} />);
const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} App={{ APP }} />);
const instance = wrapper.instance();
const site = { url: "https://foo.com" };
instance.setState({
@ -1590,7 +1626,12 @@ describe("<TopSiteList>", () => {
const site3 = { url: "https://baz.com" };
const rows = [site1, site2, site3];
let wrapper = shallow(
<TopSiteList {...DEFAULT_PROPS} TopSites={{ rows }} TopSitesRows={1} />
<TopSiteList
{...DEFAULT_PROPS}
TopSites={{ rows }}
TopSitesRows={1}
App={{ APP }}
/>
);
let instance = wrapper.instance();
instance.setState({
@ -1764,7 +1805,12 @@ describe("<TopSiteList>", () => {
rows.push({ url: `https://foo${i}.com` });
}
const wrapper = mount(
<TopSiteList {...DEFAULT_PROPS} TopSites={{ rows }} TopSitesRows={1} />
<TopSiteList
{...DEFAULT_PROPS}
TopSites={{ rows }}
TopSitesRows={1}
App={{ APP }}
/>
);
assert.lengthOf(wrapper.find("li.hide-for-narrow"), 2);
});