Bug 1573174 - Add Pocket footers, Monitor adjustments and bug fixes to New Tab Page r=k88hudson

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ed Lee 2019-08-13 02:22:39 +00:00
Родитель 645c8b23f7
Коммит ca11959d3e
32 изменённых файлов: 929 добавлений и 253 удалений

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

@ -116,7 +116,7 @@ export class ASRouterUISurface extends React.PureComponent {
this.onUserAction = this.onUserAction.bind(this);
this.fetchFlowParams = this.fetchFlowParams.bind(this);
this.state = { message: {} };
this.state = { message: {}, interruptCleared: false };
if (props.document) {
this.headerPortal = props.document.getElementById(
"header-asrouter-container"
@ -239,6 +239,9 @@ export class ASRouterUISurface extends React.PureComponent {
case "SET_MESSAGE":
this.setState({ message: action.data });
break;
case "CLEAR_INTERRUPT":
this.setState({ interruptCleared: true });
break;
case "CLEAR_MESSAGE":
this.clearMessage(action.data.id);
break;
@ -373,6 +376,7 @@ export class ASRouterUISurface extends React.PureComponent {
>
<FirstRun
document={this.props.document}
interruptCleared={this.state.interruptCleared}
message={message}
sendUserActionTelemetry={this.sendUserActionTelemetry}
executeAction={ASRouterUtils.executeAction}

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

@ -18,8 +18,9 @@ export const FLUENT_FILES = [
];
export const helpers = {
selectInterruptAndTriplets(message = {}) {
const hasInterrupt = Boolean(message.content);
selectInterruptAndTriplets(message = {}, interruptCleared) {
const hasInterrupt =
interruptCleared === true ? false : Boolean(message.content);
const hasTriplets = Boolean(message.bundle && message.bundle.length);
const UTMTerm = message.utm_term || "";
return {
@ -71,18 +72,22 @@ export class FirstRun extends React.PureComponent {
}
static getDerivedStateFromProps(props, state) {
const { message } = props;
if (message && message.id !== state.prevMessageId) {
const { message, interruptCleared } = props;
if (
interruptCleared !== state.prevInterruptCleared ||
(message && message.id !== state.prevMessageId)
) {
const {
hasTriplets,
hasInterrupt,
interrupt,
triplets,
UTMTerm,
} = helpers.selectInterruptAndTriplets(message);
} = helpers.selectInterruptAndTriplets(message, interruptCleared);
return {
prevMessageId: message.id,
prevInterruptCleared: interruptCleared,
hasInterrupt,
hasTriplets,

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

@ -20,7 +20,7 @@ export class SimpleBelowSearchSnippet extends React.PureComponent {
renderText() {
const { props } = this;
return (
return props.content.text ? (
<RichText
text={props.content.text}
customElements={this.props.customElements}
@ -28,16 +28,15 @@ export class SimpleBelowSearchSnippet extends React.PureComponent {
links={props.content.links}
sendClick={props.sendClick}
/>
);
) : null;
}
renderTitle() {
const { title } = this.props.content;
return title ? (
<h3
className={`title ${this._shouldRenderButton() ? "title-inline" : ""}`}
>
<h3 className={"title title-inline"}>
{title}
<br />
</h3>
) : null;
}
@ -121,7 +120,8 @@ export class SimpleBelowSearchSnippet extends React.PureComponent {
alt={props.content.icon_alt_text || ICON_ALT_TEXT}
/>
<div className="textContainer">
{this.renderTitle()} <p className="body">{this.renderText()}</p>
{this.renderTitle()}
<p className="body">{this.renderText()}</p>
{this.props.extraContent}
</div>
{<div className="buttonContainer">{this.renderButton()}</div>}

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

@ -5,14 +5,24 @@
&.withButton {
padding: 0 25px;
margin: auto;
min-height: 60px;
background-color: transparent;
// Add more padding if discovery stream is enabled.
.ds-outer-wrapper-breakpoint-override & {
padding: 0 50px;
@media (max-width: 865px) {
.buttonContainer {
margin: auto;
}
}
}
.snippet-hover-wrapper {
min-height: 60px;
border-radius: 4px;
&:hover {
background-color: var(--newtab-element-hover-color);
@ -23,6 +33,10 @@
// larger inset if discovery stream is enabled.
.ds-outer-wrapper-breakpoint-override & {
inset-inline-end: -8%;
@media (max-width: 865px) {
inset-inline-end: 2%;
}
}
}
}
@ -35,7 +49,6 @@
border: 0;
box-shadow: none;
position: relative;
line-height: 40px;
margin: auto;
z-index: auto;
@ -45,6 +58,7 @@
&.active {
background-color: var(--newtab-element-hover-color);
border-radius: 4px;
}
.innerWrapper {
@ -59,7 +73,8 @@
@mixin full-width-styles {
align-items: flex-start;
background-color: inherit;
background-color: transparent;
border-radius: 4px;
box-shadow: none;
flex-direction: row;
padding: 0;
@ -89,17 +104,31 @@
display: block;
inset-inline-end: 20px;
opacity: 1;
top: 24px;
top: 50%;
}
.title {
font-size: inherit;
margin: 0;
}
.title-inline {
display: inline;
}
.textContainer {
margin: 10px;
margin-inline-start: 0;
}
.icon {
margin-top: 8px;
margin-inline-start: 12px;
height: 32px;
margin-top: 15px;
width: 32px;
@mixin full-width-styles {
height: 24px;
margin-top: 10px;
width: 24px;
}
@ -116,6 +145,7 @@
&.withButton {
line-height: 20px;
margin-bottom: 10px;
min-height: 60px;
background-color: transparent;
.blockButton {
@ -123,6 +153,7 @@
inset-inline-end: -15%;
opacity: 1;
margin: auto;
top: unset;
@media (max-width: 1120px) {
inset-inline-end: 2%;
@ -135,39 +166,31 @@
.ds-outer-wrapper-breakpoint-override & {
inset-inline-end: -10%;
margin: auto;
@media (max-width: 865px) {
inset-inline-end: 2%;
}
}
}
.textContainer {
margin: 10px;
}
.title {
font-size: inherit;
margin: 0;
}
.title-inline {
display: inline;
}
.icon {
width: 42px;
height: 42px;
flex-shrink: 0;
@media (max-width: 865px) {
display: none;
}
margin: auto 0;
margin-inline-end: 10px;
}
.buttonContainer {
margin: auto;
margin-inline-end: 0;
}
}
.body {
display: inline;
position: sticky;
transform: translateY(-50%);
margin: 8px 0 0;
@media (min-width: $break-point-medium) {

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

@ -415,6 +415,7 @@
.outer-wrapper {
position: relative;
display: block;
.prefs-button {
button {

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

@ -144,6 +144,7 @@ export class _DiscoveryStreamBase extends React.PureComponent {
type={component.type}
dispatch={this.props.dispatch}
items={component.properties.items}
cta_variant={component.cta_variant}
/>
);
case "Hero":

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

@ -30,11 +30,14 @@ export class CardGrid extends React.PureComponent {
shim={rec.shim}
type={this.props.type}
context={rec.context}
sponsor={rec.sponsor}
dispatch={this.props.dispatch}
source={rec.domain}
pocket_id={rec.pocket_id}
context_type={rec.context_type}
bookmarkGuid={rec.bookmarkGuid}
cta={rec.cta}
cta_variant={this.props.cta_variant}
/>
)
);

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

@ -68,7 +68,7 @@ $col4-header-font-size: 14;
}
.excerpt {
@include limit-visibile-lines(3, 24, 15);
@include limit-visibile-lines(4, 24, 15);
}
}

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

@ -10,6 +10,54 @@ import React from "react";
import { SafeAnchor } from "../SafeAnchor/SafeAnchor";
import { DSContextFooter } from "../DSContextFooter/DSContextFooter.jsx";
export const DefaultMeta = ({
source,
title,
excerpt,
context,
context_type,
cta,
}) => (
<div className="meta">
<div className="info-wrap">
<p className="source clamp">{source}</p>
<header className="title clamp">{title}</header>
{excerpt && <p className="excerpt clamp">{excerpt}</p>}
{cta && (
<div role="link" className="cta-link icon icon-arrow" tabIndex="0">
{cta}
</div>
)}
</div>
<DSContextFooter context_type={context_type} context={context} />
</div>
);
export const VariantMeta = ({
source,
title,
excerpt,
context,
context_type,
cta,
sponsor,
}) => (
<div className="meta">
<div className="info-wrap">
<p className="source clamp">
{sponsor ? sponsor : source}
{context && ` · Sponsored`}
</p>
<header className="title clamp">{title}</header>
{excerpt && <p className="excerpt clamp">{excerpt}</p>}
</div>
{cta && <button className="button cta-button">{cta}</button>}
{!context && (
<DSContextFooter context_type={context_type} context={context} />
)}
</div>
);
export class DSCard extends React.PureComponent {
constructor(props) {
super(props);
@ -61,19 +109,27 @@ export class DSCard extends React.PureComponent {
rawSource={this.props.raw_image_src}
/>
</div>
<div className="meta">
<div className="info-wrap">
<p className="source clamp">{this.props.source}</p>
<header className="title clamp">{this.props.title}</header>
{this.props.excerpt && (
<p className="excerpt clamp">{this.props.excerpt}</p>
)}
</div>
<DSContextFooter
context_type={this.props.context_type}
{this.props.cta_variant && (
<VariantMeta
source={this.props.source}
title={this.props.title}
excerpt={this.props.excerpt}
context={this.props.context}
context_type={this.props.context_type}
cta={this.props.cta}
sponsor={this.props.sponsor}
/>
</div>
)}
{!this.props.cta_variant && (
<DefaultMeta
source={this.props.source}
title={this.props.title}
excerpt={this.props.excerpt}
context={this.props.context}
context_type={this.props.context_type}
cta={this.props.cta}
/>
)}
<ImpressionStats
campaignId={this.props.campaignId}
rows={[

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

@ -104,7 +104,7 @@ $excerpt-line-height: 20;
.excerpt {
// show only 3 lines of copy
@include limit-visibile-lines(
3,
4,
$excerpt-line-height,
$excerpt-font-size
);
@ -120,6 +120,92 @@ $excerpt-line-height: 20;
font-size: 13px;
color: $grey-50;
}
.cta-button {
@include dark-theme-only {
color: $grey-10;
background: $grey-90-30;
}
width: 100%;
margin: 12px 0 4px;
box-shadow: none;
border-radius: 4px;
height: 32px;
font-size: 14px;
padding: 5px 8px 7px;
border: 0;
color: $grey-90;
background: $grey-90-10;
&:active {
@include dark-theme-only {
background: $grey-90-70;
}
background: $grey-90-30;
}
&:hover {
@include dark-theme-only {
background: $grey-90-50;
}
background: $grey-90-30;
}
&:focus {
@include dark-theme-only {
background: $grey-90-30;
box-shadow: 0 0 0 2px $grey-80, 0 0 0 5px $blue-50-50;
}
box-shadow: 0 0 0 2px $white, 0 0 0 5px $blue-50-50;
}
}
.cta-link {
@include dark-theme-only {
color: $blue-40;
fill: $blue-40;
}
font-size: 15px;
line-height: 24px;
height: 24px;
width: auto;
background-size: auto;
background-position: right 1.5px;
padding-right: 9px;
color: $blue-60;
fill: $blue-60;
&:focus {
@include dark-theme-only {
box-shadow: 0 0 0 1px $grey-80, 0 0 0 4px $blue-50-50;
}
box-shadow: 0 0 0 1px $white, 0 0 0 4px $blue-50-50;
border-radius: 4px;
outline: 0;
}
&:active {
@include dark-theme-only {
color: $blue-50;
fill: $blue-50;
box-shadow: none;
}
color: $blue-70;
fill: $blue-70;
box-shadow: none;
}
&:hover {
text-decoration: underline;
}
}
}
header {

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

@ -9,7 +9,7 @@ import React from "react";
// Animation time is mirrored in DSContextFooter.scss
const ANIMATION_DURATION = 3000;
const StatusMessage = ({ icon, fluentID }) => (
export const StatusMessage = ({ icon, fluentID }) => (
<div className="status-message">
<span
aria-haspopup="true"
@ -26,7 +26,7 @@ export class DSContextFooter extends React.PureComponent {
return (
<div className="story-footer">
{context && <p className="story-sponsored-label">{context}</p>}
{context && <p className="story-sponsored-label clamp">{context}</p>}
<TransitionGroup component={null}>
{!context && context_type && (
<CSSTransition

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

@ -5,6 +5,7 @@ $status-dark-green: #7C6;
color: var(--newtab-text-secondary-color);
inset-inline-start: 0;
margin-top: 12px;
position: relative;
.story-sponsored-label,
.status-message {
@ -12,6 +13,7 @@ $status-dark-green: #7C6;
color: $grey-40;
}
-webkit-line-clamp: 1;
font-size: 13px;
line-height: 24px;
color: $grey-50;

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

@ -11,6 +11,7 @@ import { ImpressionStats } from "../../DiscoveryStreamImpressionStats/Impression
import { List } from "../List/List.jsx";
import React from "react";
import { SafeAnchor } from "../SafeAnchor/SafeAnchor";
import { DSContextFooter } from "../DSContextFooter/DSContextFooter.jsx";
export class Hero extends React.PureComponent {
constructor(props) {
@ -73,6 +74,7 @@ export class Hero extends React.PureComponent {
type={this.props.type}
dispatch={this.props.dispatch}
context={rec.context}
context_type={rec.context_type}
source={rec.domain}
pocket_id={rec.pocket_id}
bookmarkGuid={rec.bookmarkGuid}
@ -103,14 +105,14 @@ export class Hero extends React.PureComponent {
</div>
<div className="meta">
<div className="header-and-excerpt">
{heroRec.context ? (
<p className="context">{heroRec.context}</p>
) : (
<p className="source clamp">{heroRec.domain}</p>
)}
<p className="source clamp">{heroRec.domain}</p>
<header className="clamp">{heroRec.title}</header>
<p className="excerpt clamp">{heroRec.excerpt}</p>
</div>
<DSContextFooter
context={heroRec.context}
context_type={heroRec.context_type}
/>
</div>
<ImpressionStats
campaignId={heroRec.campaign_id}

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

@ -27,10 +27,6 @@ $card-header-in-hero-line-height: 20;
border: 0;
padding-bottom: 20px;
p {
margin-top: 4px;
}
&:hover {
border: 0;
box-shadow: none;
@ -117,6 +113,10 @@ $card-header-in-hero-line-height: 20;
flex-direction: column;
justify-content: space-between;
.header-and-excerpt {
flex: 1;
}
header {
@include dark-theme-only {
color: $white;

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

@ -10,6 +10,7 @@ import { DSLinkMenu } from "../DSLinkMenu/DSLinkMenu";
import { ImpressionStats } from "../../DiscoveryStreamImpressionStats/ImpressionStats";
import React from "react";
import { SafeAnchor } from "../SafeAnchor/SafeAnchor";
import { DSContextFooter } from "../DSContextFooter/DSContextFooter.jsx";
/**
* @note exported for testing only
@ -64,7 +65,12 @@ export class ListItem extends React.PureComponent {
url={this.props.url}
>
<div className="ds-list-item-text">
<div>
<p>
<span className="ds-list-item-info clamp">
{this.props.domain}
</span>
</p>
<div className="ds-list-item-body">
<div className="ds-list-item-title clamp">{this.props.title}</div>
{this.props.excerpt && (
<div className="ds-list-item-excerpt clamp">
@ -72,19 +78,10 @@ export class ListItem extends React.PureComponent {
</div>
)}
</div>
<p>
{this.props.context && (
<span>
<span className="ds-list-item-context clamp">
{this.props.context}
</span>
<br />
</span>
)}
<span className="ds-list-item-info clamp">
{this.props.domain}
</span>
</p>
<DSContextFooter
context={this.props.context}
context_type={this.props.context_type}
/>
</div>
<DSImage
extraClassNames="ds-list-image"
@ -157,6 +154,7 @@ export function _List(props) {
pos={rec.pos}
title={rec.title}
context={rec.context}
context_type={rec.context_type}
type={props.type}
url={rec.url}
pocket_id={rec.pocket_id}

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

@ -219,8 +219,7 @@ $item-line-height: 20;
margin: 0;
}
.ds-list-item-info,
.ds-list-item-context {
.ds-list-item-info {
@include limit-visibile-lines(1, $item-line-height, $item-font-size);
@include dark-theme-only {
color: $grey-40;
@ -235,6 +234,10 @@ $item-line-height: 20;
margin-bottom: 4px;
}
.ds-list-item-body {
flex: 1;
}
.ds-list-item-text {
display: flex;
flex-direction: column;

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

@ -196,4 +196,8 @@
&.icon-maximize {
background-image: url('#{$image-path}glyph-maximize-16.svg');
}
&.icon-arrow {
background-image: url('#{$image-path}glyph-arrow.svg');
}
}

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

@ -51,6 +51,7 @@ $grey-90-80: rgba($grey-90, 0.8);
$grey-90-90: rgba($grey-90, 0.9);
$blue-40-40: rgba($blue-40, 0.4);
$blue-50-50: rgba($blue-50, 0.5);
$blue-50-30: rgba($blue-50, 0.3);
$black: #000;

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

@ -250,6 +250,8 @@ body {
background-image: url("../data/content/assets/glyph-minimize-16.svg"); }
.icon.icon-maximize {
background-image: url("../data/content/assets/glyph-maximize-16.svg"); }
.icon.icon-arrow {
background-image: url("../data/content/assets/glyph-arrow.svg"); }
html {
height: 100%; }
@ -1949,7 +1951,7 @@ main {
.ds-column-11 .ds-card-grid.ds-card-grid-divisible-by-3 .excerpt,
.ds-column-12 .ds-card-grid.ds-card-grid-divisible-by-3 .excerpt {
font-size: 15px;
-webkit-line-clamp: 3;
-webkit-line-clamp: 4;
line-height: 24px; }
.ds-column-9 .ds-card-grid.ds-card-grid-divisible-by-4 .title,
.ds-column-10 .ds-card-grid.ds-card-grid-divisible-by-4 .title,
@ -1979,8 +1981,6 @@ main {
.ds-hero .ds-card:not(.placeholder) {
border: 0;
padding-bottom: 20px; }
.ds-hero .ds-card:not(.placeholder) p {
margin-top: 4px; }
.ds-hero .ds-card:not(.placeholder):hover {
border: 0;
box-shadow: none;
@ -2036,6 +2036,8 @@ main {
display: block;
flex-direction: column;
justify-content: space-between; }
.ds-hero .wrapper .meta .header-and-excerpt {
flex: 1; }
.ds-hero .wrapper .meta header {
font-size: 22px;
-webkit-line-clamp: 4;
@ -2390,19 +2392,19 @@ main {
font-size: 14px;
line-height: 20px;
margin: 0; }
.ds-list-item .ds-list-item-info,
.ds-list-item .ds-list-item-context {
.ds-list-item .ds-list-item-info {
font-size: 14px;
-webkit-line-clamp: 1;
line-height: 20px;
color: #737373;
font-size: 13px; }
[lwt-newtab-brighttext] .ds-list-item .ds-list-item-info, [lwt-newtab-brighttext]
.ds-list-item .ds-list-item-context {
[lwt-newtab-brighttext] .ds-list-item .ds-list-item-info {
color: #B1B1B3; }
.ds-list-item .ds-list-item-title {
font-weight: 600;
margin-bottom: 4px; }
.ds-list-item .ds-list-item-body {
flex: 1; }
.ds-list-item .ds-list-item-text {
display: flex;
flex-direction: column;
@ -2696,7 +2698,7 @@ main {
font-weight: 600; }
.ds-card .meta .excerpt {
font-size: 14px;
-webkit-line-clamp: 3;
-webkit-line-clamp: 4;
line-height: 20px; }
.ds-card .meta .source {
-webkit-line-clamp: 1;
@ -2705,6 +2707,62 @@ main {
color: #737373; }
[lwt-newtab-brighttext] .ds-card .meta .source {
color: #B1B1B3; }
.ds-card .meta .cta-button {
width: 100%;
margin: 12px 0 4px;
box-shadow: none;
border-radius: 4px;
height: 32px;
font-size: 14px;
padding: 5px 8px 7px;
border: 0;
color: #0C0C0D;
background: rgba(12, 12, 13, 0.1); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button {
color: #F9F9FA;
background: rgba(12, 12, 13, 0.3); }
.ds-card .meta .cta-button:active {
background: rgba(12, 12, 13, 0.3); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button:active {
background: rgba(12, 12, 13, 0.7); }
.ds-card .meta .cta-button:hover {
background: rgba(12, 12, 13, 0.3); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button:hover {
background: rgba(12, 12, 13, 0.5); }
.ds-card .meta .cta-button:focus {
box-shadow: 0 0 0 2px #FFF, 0 0 0 5px rgba(10, 132, 255, 0.5); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button:focus {
background: rgba(12, 12, 13, 0.3);
box-shadow: 0 0 0 2px #2A2A2E, 0 0 0 5px rgba(10, 132, 255, 0.5); }
.ds-card .meta .cta-link {
font-size: 15px;
line-height: 24px;
height: 24px;
width: auto;
background-size: auto;
background-position: right 1.5px;
padding-right: 9px;
color: #0060DF;
fill: #0060DF; }
[lwt-newtab-brighttext] .ds-card .meta .cta-link {
color: #45A1FF;
fill: #45A1FF; }
.ds-card .meta .cta-link:focus {
box-shadow: 0 0 0 1px #FFF, 0 0 0 4px rgba(10, 132, 255, 0.5);
border-radius: 4px;
outline: 0; }
[lwt-newtab-brighttext] .ds-card .meta .cta-link:focus {
box-shadow: 0 0 0 1px #2A2A2E, 0 0 0 4px rgba(10, 132, 255, 0.5); }
.ds-card .meta .cta-link:active {
color: #003EAA;
fill: #003EAA;
box-shadow: none; }
[lwt-newtab-brighttext] .ds-card .meta .cta-link:active {
color: #0A84FF;
fill: #0A84FF;
box-shadow: none; }
.ds-card .meta .cta-link:hover {
text-decoration: underline; }
.ds-card header {
line-height: 24px;
font-size: 17px;
@ -2722,9 +2780,11 @@ main {
.story-footer {
color: var(--newtab-text-secondary-color);
inset-inline-start: 0;
margin-top: 12px; }
margin-top: 12px;
position: relative; }
.story-footer .story-sponsored-label,
.story-footer .status-message {
-webkit-line-clamp: 1;
font-size: 13px;
line-height: 24px;
color: #737373; }
@ -3240,29 +3300,39 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
.below-search-snippet.withButton {
padding: 0 25px;
margin: auto;
min-height: 60px;
background-color: transparent; }
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton {
padding: 0 50px; }
.below-search-snippet.withButton .snippet-hover-wrapper:hover {
background-color: var(--newtab-element-hover-color); }
.below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
display: block; }
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
inset-inline-end: -8%; }
@media (max-width: 865px) {
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .buttonContainer {
margin: auto; } }
.below-search-snippet.withButton .snippet-hover-wrapper {
min-height: 60px;
border-radius: 4px; }
.below-search-snippet.withButton .snippet-hover-wrapper:hover {
background-color: var(--newtab-element-hover-color); }
.below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
display: block; }
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
inset-inline-end: -8%; }
@media (max-width: 865px) {
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
inset-inline-end: 2%; } }
.SimpleBelowSearchSnippet {
background-color: transparent;
border: 0;
box-shadow: none;
position: relative;
line-height: 40px;
margin: auto;
z-index: auto; }
@media (min-width: 866px) {
.SimpleBelowSearchSnippet {
width: 736px; } }
.SimpleBelowSearchSnippet.active {
background-color: var(--newtab-element-hover-color); }
background-color: var(--newtab-element-hover-color);
border-radius: 4px; }
.SimpleBelowSearchSnippet .innerWrapper {
align-items: center;
background-color: transparent;
@ -3275,7 +3345,8 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
@media (min-width: 610px) {
.SimpleBelowSearchSnippet .innerWrapper {
align-items: flex-start;
background-color: inherit;
background-color: transparent;
border-radius: 4px;
box-shadow: none;
flex-direction: row;
padding: 0;
@ -3288,7 +3359,8 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
margin: 0 60px 0 0; } }
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet .innerWrapper {
align-items: flex-start;
background-color: inherit;
background-color: transparent;
border-radius: 4px;
box-shadow: none;
flex-direction: row;
padding: 0;
@ -3298,29 +3370,38 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
display: block;
inset-inline-end: 20px;
opacity: 1;
top: 24px; }
top: 50%; }
.SimpleBelowSearchSnippet .title {
font-size: inherit;
margin: 0; }
.SimpleBelowSearchSnippet .title-inline {
display: inline; }
.SimpleBelowSearchSnippet .textContainer {
margin: 10px;
margin-inline-start: 0; }
.SimpleBelowSearchSnippet .icon {
margin-top: 8px;
margin-inline-start: 12px;
height: 32px;
margin-top: 15px;
width: 32px; }
@media (min-width: 610px) {
.SimpleBelowSearchSnippet .icon {
height: 24px;
margin-top: 10px;
width: 24px; } }
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet .icon {
height: 24px;
margin-top: 10px;
width: 24px; }
.SimpleBelowSearchSnippet.withButton {
line-height: 20px;
margin-bottom: 10px;
min-height: 60px;
background-color: transparent; }
.SimpleBelowSearchSnippet.withButton .blockButton {
display: none;
inset-inline-end: -15%;
opacity: 1;
margin: auto; }
margin: auto;
top: unset; }
@media (max-width: 1120px) {
.SimpleBelowSearchSnippet.withButton .blockButton {
inset-inline-end: 2%; } }
@ -3330,24 +3411,22 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet.withButton .blockButton {
inset-inline-end: -10%;
margin: auto; }
.SimpleBelowSearchSnippet.withButton .textContainer {
margin: 10px; }
.SimpleBelowSearchSnippet.withButton .title {
font-size: inherit;
margin: 0; }
.SimpleBelowSearchSnippet.withButton .title-inline {
display: inline; }
@media (max-width: 865px) {
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet.withButton .blockButton {
inset-inline-end: 2%; } }
.SimpleBelowSearchSnippet.withButton .icon {
width: 42px;
height: 42px;
flex-shrink: 0; }
@media (max-width: 865px) {
.SimpleBelowSearchSnippet.withButton .icon {
display: none; } }
flex-shrink: 0;
margin: auto 0;
margin-inline-end: 10px; }
.SimpleBelowSearchSnippet.withButton .buttonContainer {
margin: auto; }
margin: auto;
margin-inline-end: 0; }
.SimpleBelowSearchSnippet .body {
display: inline;
position: sticky;
transform: translateY(-50%);
margin: 8px 0 0; }
@media (min-width: 610px) {
.SimpleBelowSearchSnippet .body {
@ -4227,7 +4306,8 @@ a.firstrun-link {
position: absolute; }
.inline-onboarding .outer-wrapper {
position: relative; }
position: relative;
display: block; }
.inline-onboarding .outer-wrapper .prefs-button button {
position: absolute; }

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

@ -253,6 +253,8 @@ body {
background-image: url("../data/content/assets/glyph-minimize-16.svg"); }
.icon.icon-maximize {
background-image: url("../data/content/assets/glyph-maximize-16.svg"); }
.icon.icon-arrow {
background-image: url("../data/content/assets/glyph-arrow.svg"); }
html {
height: 100%; }
@ -1952,7 +1954,7 @@ main {
.ds-column-11 .ds-card-grid.ds-card-grid-divisible-by-3 .excerpt,
.ds-column-12 .ds-card-grid.ds-card-grid-divisible-by-3 .excerpt {
font-size: 15px;
-webkit-line-clamp: 3;
-webkit-line-clamp: 4;
line-height: 24px; }
.ds-column-9 .ds-card-grid.ds-card-grid-divisible-by-4 .title,
.ds-column-10 .ds-card-grid.ds-card-grid-divisible-by-4 .title,
@ -1982,8 +1984,6 @@ main {
.ds-hero .ds-card:not(.placeholder) {
border: 0;
padding-bottom: 20px; }
.ds-hero .ds-card:not(.placeholder) p {
margin-top: 4px; }
.ds-hero .ds-card:not(.placeholder):hover {
border: 0;
box-shadow: none;
@ -2039,6 +2039,8 @@ main {
display: block;
flex-direction: column;
justify-content: space-between; }
.ds-hero .wrapper .meta .header-and-excerpt {
flex: 1; }
.ds-hero .wrapper .meta header {
font-size: 22px;
-webkit-line-clamp: 4;
@ -2393,19 +2395,19 @@ main {
font-size: 14px;
line-height: 20px;
margin: 0; }
.ds-list-item .ds-list-item-info,
.ds-list-item .ds-list-item-context {
.ds-list-item .ds-list-item-info {
font-size: 14px;
-webkit-line-clamp: 1;
line-height: 20px;
color: #737373;
font-size: 13px; }
[lwt-newtab-brighttext] .ds-list-item .ds-list-item-info, [lwt-newtab-brighttext]
.ds-list-item .ds-list-item-context {
[lwt-newtab-brighttext] .ds-list-item .ds-list-item-info {
color: #B1B1B3; }
.ds-list-item .ds-list-item-title {
font-weight: 600;
margin-bottom: 4px; }
.ds-list-item .ds-list-item-body {
flex: 1; }
.ds-list-item .ds-list-item-text {
display: flex;
flex-direction: column;
@ -2699,7 +2701,7 @@ main {
font-weight: 600; }
.ds-card .meta .excerpt {
font-size: 14px;
-webkit-line-clamp: 3;
-webkit-line-clamp: 4;
line-height: 20px; }
.ds-card .meta .source {
-webkit-line-clamp: 1;
@ -2708,6 +2710,62 @@ main {
color: #737373; }
[lwt-newtab-brighttext] .ds-card .meta .source {
color: #B1B1B3; }
.ds-card .meta .cta-button {
width: 100%;
margin: 12px 0 4px;
box-shadow: none;
border-radius: 4px;
height: 32px;
font-size: 14px;
padding: 5px 8px 7px;
border: 0;
color: #0C0C0D;
background: rgba(12, 12, 13, 0.1); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button {
color: #F9F9FA;
background: rgba(12, 12, 13, 0.3); }
.ds-card .meta .cta-button:active {
background: rgba(12, 12, 13, 0.3); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button:active {
background: rgba(12, 12, 13, 0.7); }
.ds-card .meta .cta-button:hover {
background: rgba(12, 12, 13, 0.3); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button:hover {
background: rgba(12, 12, 13, 0.5); }
.ds-card .meta .cta-button:focus {
box-shadow: 0 0 0 2px #FFF, 0 0 0 5px rgba(10, 132, 255, 0.5); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button:focus {
background: rgba(12, 12, 13, 0.3);
box-shadow: 0 0 0 2px #2A2A2E, 0 0 0 5px rgba(10, 132, 255, 0.5); }
.ds-card .meta .cta-link {
font-size: 15px;
line-height: 24px;
height: 24px;
width: auto;
background-size: auto;
background-position: right 1.5px;
padding-right: 9px;
color: #0060DF;
fill: #0060DF; }
[lwt-newtab-brighttext] .ds-card .meta .cta-link {
color: #45A1FF;
fill: #45A1FF; }
.ds-card .meta .cta-link:focus {
box-shadow: 0 0 0 1px #FFF, 0 0 0 4px rgba(10, 132, 255, 0.5);
border-radius: 4px;
outline: 0; }
[lwt-newtab-brighttext] .ds-card .meta .cta-link:focus {
box-shadow: 0 0 0 1px #2A2A2E, 0 0 0 4px rgba(10, 132, 255, 0.5); }
.ds-card .meta .cta-link:active {
color: #003EAA;
fill: #003EAA;
box-shadow: none; }
[lwt-newtab-brighttext] .ds-card .meta .cta-link:active {
color: #0A84FF;
fill: #0A84FF;
box-shadow: none; }
.ds-card .meta .cta-link:hover {
text-decoration: underline; }
.ds-card header {
line-height: 24px;
font-size: 17px;
@ -2725,9 +2783,11 @@ main {
.story-footer {
color: var(--newtab-text-secondary-color);
inset-inline-start: 0;
margin-top: 12px; }
margin-top: 12px;
position: relative; }
.story-footer .story-sponsored-label,
.story-footer .status-message {
-webkit-line-clamp: 1;
font-size: 13px;
line-height: 24px;
color: #737373; }
@ -3243,29 +3303,39 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
.below-search-snippet.withButton {
padding: 0 25px;
margin: auto;
min-height: 60px;
background-color: transparent; }
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton {
padding: 0 50px; }
.below-search-snippet.withButton .snippet-hover-wrapper:hover {
background-color: var(--newtab-element-hover-color); }
.below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
display: block; }
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
inset-inline-end: -8%; }
@media (max-width: 865px) {
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .buttonContainer {
margin: auto; } }
.below-search-snippet.withButton .snippet-hover-wrapper {
min-height: 60px;
border-radius: 4px; }
.below-search-snippet.withButton .snippet-hover-wrapper:hover {
background-color: var(--newtab-element-hover-color); }
.below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
display: block; }
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
inset-inline-end: -8%; }
@media (max-width: 865px) {
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
inset-inline-end: 2%; } }
.SimpleBelowSearchSnippet {
background-color: transparent;
border: 0;
box-shadow: none;
position: relative;
line-height: 40px;
margin: auto;
z-index: auto; }
@media (min-width: 866px) {
.SimpleBelowSearchSnippet {
width: 736px; } }
.SimpleBelowSearchSnippet.active {
background-color: var(--newtab-element-hover-color); }
background-color: var(--newtab-element-hover-color);
border-radius: 4px; }
.SimpleBelowSearchSnippet .innerWrapper {
align-items: center;
background-color: transparent;
@ -3278,7 +3348,8 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
@media (min-width: 610px) {
.SimpleBelowSearchSnippet .innerWrapper {
align-items: flex-start;
background-color: inherit;
background-color: transparent;
border-radius: 4px;
box-shadow: none;
flex-direction: row;
padding: 0;
@ -3291,7 +3362,8 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
margin: 0 60px 0 0; } }
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet .innerWrapper {
align-items: flex-start;
background-color: inherit;
background-color: transparent;
border-radius: 4px;
box-shadow: none;
flex-direction: row;
padding: 0;
@ -3301,29 +3373,38 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
display: block;
inset-inline-end: 20px;
opacity: 1;
top: 24px; }
top: 50%; }
.SimpleBelowSearchSnippet .title {
font-size: inherit;
margin: 0; }
.SimpleBelowSearchSnippet .title-inline {
display: inline; }
.SimpleBelowSearchSnippet .textContainer {
margin: 10px;
margin-inline-start: 0; }
.SimpleBelowSearchSnippet .icon {
margin-top: 8px;
margin-inline-start: 12px;
height: 32px;
margin-top: 15px;
width: 32px; }
@media (min-width: 610px) {
.SimpleBelowSearchSnippet .icon {
height: 24px;
margin-top: 10px;
width: 24px; } }
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet .icon {
height: 24px;
margin-top: 10px;
width: 24px; }
.SimpleBelowSearchSnippet.withButton {
line-height: 20px;
margin-bottom: 10px;
min-height: 60px;
background-color: transparent; }
.SimpleBelowSearchSnippet.withButton .blockButton {
display: none;
inset-inline-end: -15%;
opacity: 1;
margin: auto; }
margin: auto;
top: unset; }
@media (max-width: 1120px) {
.SimpleBelowSearchSnippet.withButton .blockButton {
inset-inline-end: 2%; } }
@ -3333,24 +3414,22 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet.withButton .blockButton {
inset-inline-end: -10%;
margin: auto; }
.SimpleBelowSearchSnippet.withButton .textContainer {
margin: 10px; }
.SimpleBelowSearchSnippet.withButton .title {
font-size: inherit;
margin: 0; }
.SimpleBelowSearchSnippet.withButton .title-inline {
display: inline; }
@media (max-width: 865px) {
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet.withButton .blockButton {
inset-inline-end: 2%; } }
.SimpleBelowSearchSnippet.withButton .icon {
width: 42px;
height: 42px;
flex-shrink: 0; }
@media (max-width: 865px) {
.SimpleBelowSearchSnippet.withButton .icon {
display: none; } }
flex-shrink: 0;
margin: auto 0;
margin-inline-end: 10px; }
.SimpleBelowSearchSnippet.withButton .buttonContainer {
margin: auto; }
margin: auto;
margin-inline-end: 0; }
.SimpleBelowSearchSnippet .body {
display: inline;
position: sticky;
transform: translateY(-50%);
margin: 8px 0 0; }
@media (min-width: 610px) {
.SimpleBelowSearchSnippet .body {
@ -4230,7 +4309,8 @@ a.firstrun-link {
position: absolute; }
.inline-onboarding .outer-wrapper {
position: relative; }
position: relative;
display: block; }
.inline-onboarding .outer-wrapper .prefs-button button {
position: absolute; }

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

@ -250,6 +250,8 @@ body {
background-image: url("../data/content/assets/glyph-minimize-16.svg"); }
.icon.icon-maximize {
background-image: url("../data/content/assets/glyph-maximize-16.svg"); }
.icon.icon-arrow {
background-image: url("../data/content/assets/glyph-arrow.svg"); }
html {
height: 100%; }
@ -1949,7 +1951,7 @@ main {
.ds-column-11 .ds-card-grid.ds-card-grid-divisible-by-3 .excerpt,
.ds-column-12 .ds-card-grid.ds-card-grid-divisible-by-3 .excerpt {
font-size: 15px;
-webkit-line-clamp: 3;
-webkit-line-clamp: 4;
line-height: 24px; }
.ds-column-9 .ds-card-grid.ds-card-grid-divisible-by-4 .title,
.ds-column-10 .ds-card-grid.ds-card-grid-divisible-by-4 .title,
@ -1979,8 +1981,6 @@ main {
.ds-hero .ds-card:not(.placeholder) {
border: 0;
padding-bottom: 20px; }
.ds-hero .ds-card:not(.placeholder) p {
margin-top: 4px; }
.ds-hero .ds-card:not(.placeholder):hover {
border: 0;
box-shadow: none;
@ -2036,6 +2036,8 @@ main {
display: block;
flex-direction: column;
justify-content: space-between; }
.ds-hero .wrapper .meta .header-and-excerpt {
flex: 1; }
.ds-hero .wrapper .meta header {
font-size: 22px;
-webkit-line-clamp: 4;
@ -2390,19 +2392,19 @@ main {
font-size: 14px;
line-height: 20px;
margin: 0; }
.ds-list-item .ds-list-item-info,
.ds-list-item .ds-list-item-context {
.ds-list-item .ds-list-item-info {
font-size: 14px;
-webkit-line-clamp: 1;
line-height: 20px;
color: #737373;
font-size: 13px; }
[lwt-newtab-brighttext] .ds-list-item .ds-list-item-info, [lwt-newtab-brighttext]
.ds-list-item .ds-list-item-context {
[lwt-newtab-brighttext] .ds-list-item .ds-list-item-info {
color: #B1B1B3; }
.ds-list-item .ds-list-item-title {
font-weight: 600;
margin-bottom: 4px; }
.ds-list-item .ds-list-item-body {
flex: 1; }
.ds-list-item .ds-list-item-text {
display: flex;
flex-direction: column;
@ -2696,7 +2698,7 @@ main {
font-weight: 600; }
.ds-card .meta .excerpt {
font-size: 14px;
-webkit-line-clamp: 3;
-webkit-line-clamp: 4;
line-height: 20px; }
.ds-card .meta .source {
-webkit-line-clamp: 1;
@ -2705,6 +2707,62 @@ main {
color: #737373; }
[lwt-newtab-brighttext] .ds-card .meta .source {
color: #B1B1B3; }
.ds-card .meta .cta-button {
width: 100%;
margin: 12px 0 4px;
box-shadow: none;
border-radius: 4px;
height: 32px;
font-size: 14px;
padding: 5px 8px 7px;
border: 0;
color: #0C0C0D;
background: rgba(12, 12, 13, 0.1); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button {
color: #F9F9FA;
background: rgba(12, 12, 13, 0.3); }
.ds-card .meta .cta-button:active {
background: rgba(12, 12, 13, 0.3); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button:active {
background: rgba(12, 12, 13, 0.7); }
.ds-card .meta .cta-button:hover {
background: rgba(12, 12, 13, 0.3); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button:hover {
background: rgba(12, 12, 13, 0.5); }
.ds-card .meta .cta-button:focus {
box-shadow: 0 0 0 2px #FFF, 0 0 0 5px rgba(10, 132, 255, 0.5); }
[lwt-newtab-brighttext] .ds-card .meta .cta-button:focus {
background: rgba(12, 12, 13, 0.3);
box-shadow: 0 0 0 2px #2A2A2E, 0 0 0 5px rgba(10, 132, 255, 0.5); }
.ds-card .meta .cta-link {
font-size: 15px;
line-height: 24px;
height: 24px;
width: auto;
background-size: auto;
background-position: right 1.5px;
padding-right: 9px;
color: #0060DF;
fill: #0060DF; }
[lwt-newtab-brighttext] .ds-card .meta .cta-link {
color: #45A1FF;
fill: #45A1FF; }
.ds-card .meta .cta-link:focus {
box-shadow: 0 0 0 1px #FFF, 0 0 0 4px rgba(10, 132, 255, 0.5);
border-radius: 4px;
outline: 0; }
[lwt-newtab-brighttext] .ds-card .meta .cta-link:focus {
box-shadow: 0 0 0 1px #2A2A2E, 0 0 0 4px rgba(10, 132, 255, 0.5); }
.ds-card .meta .cta-link:active {
color: #003EAA;
fill: #003EAA;
box-shadow: none; }
[lwt-newtab-brighttext] .ds-card .meta .cta-link:active {
color: #0A84FF;
fill: #0A84FF;
box-shadow: none; }
.ds-card .meta .cta-link:hover {
text-decoration: underline; }
.ds-card header {
line-height: 24px;
font-size: 17px;
@ -2722,9 +2780,11 @@ main {
.story-footer {
color: var(--newtab-text-secondary-color);
inset-inline-start: 0;
margin-top: 12px; }
margin-top: 12px;
position: relative; }
.story-footer .story-sponsored-label,
.story-footer .status-message {
-webkit-line-clamp: 1;
font-size: 13px;
line-height: 24px;
color: #737373; }
@ -3240,29 +3300,39 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
.below-search-snippet.withButton {
padding: 0 25px;
margin: auto;
min-height: 60px;
background-color: transparent; }
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton {
padding: 0 50px; }
.below-search-snippet.withButton .snippet-hover-wrapper:hover {
background-color: var(--newtab-element-hover-color); }
.below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
display: block; }
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
inset-inline-end: -8%; }
@media (max-width: 865px) {
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .buttonContainer {
margin: auto; } }
.below-search-snippet.withButton .snippet-hover-wrapper {
min-height: 60px;
border-radius: 4px; }
.below-search-snippet.withButton .snippet-hover-wrapper:hover {
background-color: var(--newtab-element-hover-color); }
.below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
display: block; }
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
inset-inline-end: -8%; }
@media (max-width: 865px) {
.ds-outer-wrapper-breakpoint-override .below-search-snippet.withButton .snippet-hover-wrapper:hover .blockButton {
inset-inline-end: 2%; } }
.SimpleBelowSearchSnippet {
background-color: transparent;
border: 0;
box-shadow: none;
position: relative;
line-height: 40px;
margin: auto;
z-index: auto; }
@media (min-width: 866px) {
.SimpleBelowSearchSnippet {
width: 736px; } }
.SimpleBelowSearchSnippet.active {
background-color: var(--newtab-element-hover-color); }
background-color: var(--newtab-element-hover-color);
border-radius: 4px; }
.SimpleBelowSearchSnippet .innerWrapper {
align-items: center;
background-color: transparent;
@ -3275,7 +3345,8 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
@media (min-width: 610px) {
.SimpleBelowSearchSnippet .innerWrapper {
align-items: flex-start;
background-color: inherit;
background-color: transparent;
border-radius: 4px;
box-shadow: none;
flex-direction: row;
padding: 0;
@ -3288,7 +3359,8 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
margin: 0 60px 0 0; } }
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet .innerWrapper {
align-items: flex-start;
background-color: inherit;
background-color: transparent;
border-radius: 4px;
box-shadow: none;
flex-direction: row;
padding: 0;
@ -3298,29 +3370,38 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
display: block;
inset-inline-end: 20px;
opacity: 1;
top: 24px; }
top: 50%; }
.SimpleBelowSearchSnippet .title {
font-size: inherit;
margin: 0; }
.SimpleBelowSearchSnippet .title-inline {
display: inline; }
.SimpleBelowSearchSnippet .textContainer {
margin: 10px;
margin-inline-start: 0; }
.SimpleBelowSearchSnippet .icon {
margin-top: 8px;
margin-inline-start: 12px;
height: 32px;
margin-top: 15px;
width: 32px; }
@media (min-width: 610px) {
.SimpleBelowSearchSnippet .icon {
height: 24px;
margin-top: 10px;
width: 24px; } }
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet .icon {
height: 24px;
margin-top: 10px;
width: 24px; }
.SimpleBelowSearchSnippet.withButton {
line-height: 20px;
margin-bottom: 10px;
min-height: 60px;
background-color: transparent; }
.SimpleBelowSearchSnippet.withButton .blockButton {
display: none;
inset-inline-end: -15%;
opacity: 1;
margin: auto; }
margin: auto;
top: unset; }
@media (max-width: 1120px) {
.SimpleBelowSearchSnippet.withButton .blockButton {
inset-inline-end: 2%; } }
@ -3330,24 +3411,22 @@ body[lwt-newtab-brighttext] .scene2Icon .icon-light-theme {
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet.withButton .blockButton {
inset-inline-end: -10%;
margin: auto; }
.SimpleBelowSearchSnippet.withButton .textContainer {
margin: 10px; }
.SimpleBelowSearchSnippet.withButton .title {
font-size: inherit;
margin: 0; }
.SimpleBelowSearchSnippet.withButton .title-inline {
display: inline; }
@media (max-width: 865px) {
.ds-outer-wrapper-breakpoint-override .SimpleBelowSearchSnippet.withButton .blockButton {
inset-inline-end: 2%; } }
.SimpleBelowSearchSnippet.withButton .icon {
width: 42px;
height: 42px;
flex-shrink: 0; }
@media (max-width: 865px) {
.SimpleBelowSearchSnippet.withButton .icon {
display: none; } }
flex-shrink: 0;
margin: auto 0;
margin-inline-end: 10px; }
.SimpleBelowSearchSnippet.withButton .buttonContainer {
margin: auto; }
margin: auto;
margin-inline-end: 0; }
.SimpleBelowSearchSnippet .body {
display: inline;
position: sticky;
transform: translateY(-50%);
margin: 8px 0 0; }
@media (min-width: 610px) {
.SimpleBelowSearchSnippet .body {
@ -4227,7 +4306,8 @@ a.firstrun-link {
position: absolute; }
.inline-onboarding .outer-wrapper {
position: relative; }
position: relative;
display: block; }
.inline-onboarding .outer-wrapper .prefs-button button {
position: absolute; }

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

@ -1907,7 +1907,8 @@ class ASRouterUISurface extends react__WEBPACK_IMPORTED_MODULE_6___default.a.Pur
this.onUserAction = this.onUserAction.bind(this);
this.fetchFlowParams = this.fetchFlowParams.bind(this);
this.state = {
message: {}
message: {},
interruptCleared: false
};
if (props.document) {
@ -2063,6 +2064,12 @@ class ASRouterUISurface extends react__WEBPACK_IMPORTED_MODULE_6___default.a.Pur
});
break;
case "CLEAR_INTERRUPT":
this.setState({
interruptCleared: true
});
break;
case "CLEAR_MESSAGE":
this.clearMessage(action.data.id);
break;
@ -2216,6 +2223,7 @@ class ASRouterUISurface extends react__WEBPACK_IMPORTED_MODULE_6___default.a.Pur
document: this.props.document
}, react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement(_templates_FirstRun_FirstRun__WEBPACK_IMPORTED_MODULE_9__["FirstRun"], {
document: this.props.document,
interruptCleared: this.state.interruptCleared,
message: message,
sendUserActionTelemetry: this.sendUserActionTelemetry,
executeAction: ASRouterUtils.executeAction,
@ -7871,7 +7879,6 @@ var external_ReactTransitionGroup_ = __webpack_require__(34);
// Animation time is mirrored in DSContextFooter.scss
const ANIMATION_DURATION = 3000;
const StatusMessage = ({
icon,
fluentID
@ -7884,7 +7891,6 @@ const StatusMessage = ({
className: "story-context-label",
"data-l10n-id": fluentID
}));
class DSContextFooter_DSContextFooter extends external_React_default.a.PureComponent {
render() {
const {
@ -7898,7 +7904,7 @@ class DSContextFooter_DSContextFooter extends external_React_default.a.PureCompo
return external_React_default.a.createElement("div", {
className: "story-footer"
}, context && external_React_default.a.createElement("p", {
className: "story-sponsored-label"
className: "story-sponsored-label clamp"
}, context), external_React_default.a.createElement(external_ReactTransitionGroup_["TransitionGroup"], {
component: null
}, !context && context_type && external_React_default.a.createElement(external_ReactTransitionGroup_["CSSTransition"], {
@ -7923,6 +7929,55 @@ class DSContextFooter_DSContextFooter extends external_React_default.a.PureCompo
const DefaultMeta = ({
source,
title,
excerpt,
context,
context_type,
cta
}) => external_React_default.a.createElement("div", {
className: "meta"
}, external_React_default.a.createElement("div", {
className: "info-wrap"
}, external_React_default.a.createElement("p", {
className: "source clamp"
}, source), external_React_default.a.createElement("header", {
className: "title clamp"
}, title), excerpt && external_React_default.a.createElement("p", {
className: "excerpt clamp"
}, excerpt), cta && external_React_default.a.createElement("div", {
role: "link",
className: "cta-link icon icon-arrow",
tabIndex: "0"
}, cta)), external_React_default.a.createElement(DSContextFooter_DSContextFooter, {
context_type: context_type,
context: context
}));
const VariantMeta = ({
source,
title,
excerpt,
context,
context_type,
cta,
sponsor
}) => external_React_default.a.createElement("div", {
className: "meta"
}, external_React_default.a.createElement("div", {
className: "info-wrap"
}, external_React_default.a.createElement("p", {
className: "source clamp"
}, sponsor ? sponsor : source, context && ` · Sponsored`), external_React_default.a.createElement("header", {
className: "title clamp"
}, title), excerpt && external_React_default.a.createElement("p", {
className: "excerpt clamp"
}, excerpt)), cta && external_React_default.a.createElement("button", {
className: "button cta-button"
}, cta), !context && external_React_default.a.createElement(DSContextFooter_DSContextFooter, {
context_type: context_type,
context: context
}));
class DSCard_DSCard extends external_React_default.a.PureComponent {
constructor(props) {
super(props);
@ -7964,20 +8019,22 @@ class DSCard_DSCard extends external_React_default.a.PureComponent {
extraClassNames: "img",
source: this.props.image_src,
rawSource: this.props.raw_image_src
})), external_React_default.a.createElement("div", {
className: "meta"
}, external_React_default.a.createElement("div", {
className: "info-wrap"
}, external_React_default.a.createElement("p", {
className: "source clamp"
}, this.props.source), external_React_default.a.createElement("header", {
className: "title clamp"
}, this.props.title), this.props.excerpt && external_React_default.a.createElement("p", {
className: "excerpt clamp"
}, this.props.excerpt)), external_React_default.a.createElement(DSContextFooter_DSContextFooter, {
})), this.props.cta_variant && external_React_default.a.createElement(VariantMeta, {
source: this.props.source,
title: this.props.title,
excerpt: this.props.excerpt,
context: this.props.context,
context_type: this.props.context_type,
context: this.props.context
})), external_React_default.a.createElement(ImpressionStats["ImpressionStats"], {
cta: this.props.cta,
sponsor: this.props.sponsor
}), !this.props.cta_variant && external_React_default.a.createElement(DefaultMeta, {
source: this.props.source,
title: this.props.title,
excerpt: this.props.excerpt,
context: this.props.context,
context_type: this.props.context_type,
cta: this.props.cta
}), external_React_default.a.createElement(ImpressionStats["ImpressionStats"], {
campaignId: this.props.campaignId,
rows: [{
id: this.props.id,
@ -8129,11 +8186,14 @@ class CardGrid_CardGrid extends external_React_default.a.PureComponent {
shim: rec.shim,
type: this.props.type,
context: rec.context,
sponsor: rec.sponsor,
dispatch: this.props.dispatch,
source: rec.domain,
pocket_id: rec.pocket_id,
context_type: rec.context_type,
bookmarkGuid: rec.bookmarkGuid
bookmarkGuid: rec.bookmarkGuid,
cta: rec.cta,
cta_variant: this.props.cta_variant
}));
}
@ -8222,6 +8282,7 @@ class DSMessage_DSMessage extends external_React_default.a.PureComponent {
/**
* @note exported for testing only
*/
@ -8265,15 +8326,18 @@ class List_ListItem extends external_React_default.a.PureComponent {
url: this.props.url
}, external_React_default.a.createElement("div", {
className: "ds-list-item-text"
}, external_React_default.a.createElement("div", null, external_React_default.a.createElement("div", {
}, external_React_default.a.createElement("p", null, external_React_default.a.createElement("span", {
className: "ds-list-item-info clamp"
}, this.props.domain)), external_React_default.a.createElement("div", {
className: "ds-list-item-body"
}, external_React_default.a.createElement("div", {
className: "ds-list-item-title clamp"
}, this.props.title), this.props.excerpt && external_React_default.a.createElement("div", {
className: "ds-list-item-excerpt clamp"
}, this.props.excerpt)), external_React_default.a.createElement("p", null, this.props.context && external_React_default.a.createElement("span", null, external_React_default.a.createElement("span", {
className: "ds-list-item-context clamp"
}, this.props.context), external_React_default.a.createElement("br", null)), external_React_default.a.createElement("span", {
className: "ds-list-item-info clamp"
}, this.props.domain))), external_React_default.a.createElement(DSImage_DSImage, {
}, this.props.excerpt)), external_React_default.a.createElement(DSContextFooter_DSContextFooter, {
context: this.props.context,
context_type: this.props.context_type
})), external_React_default.a.createElement(DSImage_DSImage, {
extraClassNames: "ds-list-image",
source: this.props.image_src,
rawSource: this.props.raw_image_src
@ -8332,6 +8396,7 @@ function _List(props) {
pos: rec.pos,
title: rec.title,
context: rec.context,
context_type: rec.context_type,
type: props.type,
url: rec.url,
pocket_id: rec.pocket_id,
@ -8395,6 +8460,7 @@ const List = Object(external_ReactRedux_["connect"])(state => ({
class Hero_Hero extends external_React_default.a.PureComponent {
constructor(props) {
super(props);
@ -8444,6 +8510,7 @@ class Hero_Hero extends external_React_default.a.PureComponent {
type: this.props.type,
dispatch: this.props.dispatch,
context: rec.context,
context_type: rec.context_type,
source: rec.domain,
pocket_id: rec.pocket_id,
bookmarkGuid: rec.bookmarkGuid
@ -8473,15 +8540,16 @@ class Hero_Hero extends external_React_default.a.PureComponent {
className: "meta"
}, external_React_default.a.createElement("div", {
className: "header-and-excerpt"
}, heroRec.context ? external_React_default.a.createElement("p", {
className: "context"
}, heroRec.context) : external_React_default.a.createElement("p", {
}, external_React_default.a.createElement("p", {
className: "source clamp"
}, heroRec.domain), external_React_default.a.createElement("header", {
className: "clamp"
}, heroRec.title), external_React_default.a.createElement("p", {
className: "excerpt clamp"
}, heroRec.excerpt))), external_React_default.a.createElement(ImpressionStats["ImpressionStats"], {
}, heroRec.excerpt)), external_React_default.a.createElement(DSContextFooter_DSContextFooter, {
context: heroRec.context,
context_type: heroRec.context_type
})), external_React_default.a.createElement(ImpressionStats["ImpressionStats"], {
campaignId: heroRec.campaign_id,
rows: [{
id: heroRec.id,
@ -9021,7 +9089,8 @@ class DiscoveryStreamBase_DiscoveryStreamBase extends external_React_default.a.P
border: component.properties.border,
type: component.type,
dispatch: this.props.dispatch,
items: component.properties.items
items: component.properties.items,
cta_variant: component.cta_variant
});
case "Hero":
@ -11027,13 +11096,13 @@ class SimpleBelowSearchSnippet_SimpleBelowSearchSnippet extends external_React_d
const {
props
} = this;
return external_React_default.a.createElement(RichText["RichText"], {
return props.content.text ? external_React_default.a.createElement(RichText["RichText"], {
text: props.content.text,
customElements: this.props.customElements,
localization_id: "text",
links: props.content.links,
sendClick: props.sendClick
});
}) : null;
}
renderTitle() {
@ -11041,8 +11110,8 @@ class SimpleBelowSearchSnippet_SimpleBelowSearchSnippet extends external_React_d
title
} = this.props.content;
return title ? external_React_default.a.createElement("h3", {
className: `title ${this._shouldRenderButton() ? "title-inline" : ""}`
}, title) : null;
className: "title title-inline"
}, title, external_React_default.a.createElement("br", null)) : null;
}
async onButtonClick() {
@ -11123,7 +11192,7 @@ class SimpleBelowSearchSnippet_SimpleBelowSearchSnippet extends external_React_d
alt: props.content.icon_alt_text || SimpleBelowSearchSnippet_ICON_ALT_TEXT
}), external_React_default.a.createElement("div", {
className: "textContainer"
}, this.renderTitle(), " ", external_React_default.a.createElement("p", {
}, this.renderTitle(), external_React_default.a.createElement("p", {
className: "body"
}, this.renderText()), this.props.extraContent), external_React_default.a.createElement("div", {
className: "buttonContainer"
@ -13550,8 +13619,8 @@ var addUtmParams = __webpack_require__(22);
const TRANSITION_LENGTH = 500;
const FLUENT_FILES = ["branding/brand.ftl", "browser/branding/brandings.ftl", "browser/branding/sync-brand.ftl", "browser/newtab/onboarding.ftl"];
const helpers = {
selectInterruptAndTriplets(message = {}) {
const hasInterrupt = Boolean(message.content);
selectInterruptAndTriplets(message = {}, interruptCleared) {
const hasInterrupt = interruptCleared === true ? false : Boolean(message.content);
const hasTriplets = Boolean(message.bundle && message.bundle.length);
const UTMTerm = message.utm_term || "";
return {
@ -13595,19 +13664,21 @@ class FirstRun_FirstRun extends external_React_default.a.PureComponent {
static getDerivedStateFromProps(props, state) {
const {
message
message,
interruptCleared
} = props;
if (message && message.id !== state.prevMessageId) {
if (interruptCleared !== state.prevInterruptCleared || message && message.id !== state.prevMessageId) {
const {
hasTriplets,
hasInterrupt,
interrupt,
triplets,
UTMTerm
} = helpers.selectInterruptAndTriplets(message);
} = helpers.selectInterruptAndTriplets(message, interruptCleared);
return {
prevMessageId: message.id,
prevInterruptCleared: interruptCleared,
hasInterrupt,
hasTriplets,
interrupt,

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

@ -0,0 +1 @@
<svg width="5" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M.248 8.204a.77.77 0 0 1 1.088.044L4.8 12l-3.464 3.752a.77.77 0 1 1-1.132-1.045L2.704 12l-2.5-2.707a.77.77 0 0 1 .044-1.089z" fill="context-fill"/></svg>

После

Ширина:  |  Высота:  |  Размер: 276 B

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

@ -1644,10 +1644,8 @@ class _ASRouter {
"webextension-install-notify"
);
this.messageChannel.sendAsyncMessage(OUTGOING_MESSAGE_NAME, {
type: "CLEAR_MESSAGE",
data: { id: "RETURN_TO_AMO_1" },
type: "CLEAR_INTERRUPT",
});
this.blockMessageById("RETURN_TO_AMO_1");
};
Services.obs.addObserver(addonInstallObs, "webextension-install-notify");
}

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

@ -6,30 +6,38 @@
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
const { NewTabUtils } = ChromeUtils.import(
ChromeUtils.defineModuleGetter(
this,
"NewTabUtils",
"resource://gre/modules/NewTabUtils.jsm"
);
const { setTimeout, clearTimeout } = ChromeUtils.import(
"resource://gre/modules/Timer.jsm"
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(
this,
"Services",
"resource://gre/modules/Services.jsm"
);
XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]);
ChromeUtils.defineModuleGetter(
this,
"perfService",
"resource://activity-stream/common/PerfService.jsm"
);
const { UserDomainAffinityProvider } = ChromeUtils.import(
ChromeUtils.defineModuleGetter(
this,
"UserDomainAffinityProvider",
"resource://activity-stream/lib/UserDomainAffinityProvider.jsm"
);
const { actionTypes: at, actionCreators: ac } = ChromeUtils.import(
"resource://activity-stream/common/Actions.jsm"
);
const { PersistentCache } = ChromeUtils.import(
ChromeUtils.defineModuleGetter(
this,
"PersistentCache",
"resource://activity-stream/lib/PersistentCache.jsm"
);
XPCOMUtils.defineLazyServiceGetters(this, {
gUUIDGenerator: ["@mozilla.org/uuid-generator;1", "nsIUUIDGenerator"],
});
@ -329,7 +337,12 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
type: at.DISCOVERY_STREAM_LAYOUT_UPDATE,
data: layout,
});
if (layout.spocs && layout.spocs.url) {
if (
layout.spocs &&
layout.spocs.url &&
layout.spocs.url !==
this.store.getState().DiscoveryStream.spocs.spocs_endpoint
) {
sendUpdate({
type: at.DISCOVERY_STREAM_SPOCS_ENDPOINT,
data: layout.spocs.url,
@ -1300,6 +1313,7 @@ defaultLayoutResp = {
components: [
{
type: "CardGrid",
cta_variant: false,
properties: {
items: 21,
},

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

@ -402,6 +402,21 @@ const MESSAGES = () => [
block_button_text: "Block",
},
},
{
id: "SIMPLE_BELOW_SEARCH_TEST_TITLE",
template: "simple_below_search_snippet",
content: {
icon: TEST_ICON,
icon_dark_theme: TEST_ICON_BW,
title: "See if you've been part of an online data breach.",
text:
"Securely store passwords, bookmarks, and more with a Firefox Account. <syncLink>Sign up</syncLink>",
links: {
syncLink: { url: "https://www.mozilla.org/en-US/firefox/accounts" },
},
block_button_text: "Block",
},
},
{
id: "SPECIAL_SNIPPET_BUTTON_1",
template: "simple_below_search_snippet",
@ -415,6 +430,32 @@ const MESSAGES = () => [
block_button_text: "Block",
},
},
{
id: "SPECIAL_SNIPPET_LONG_CONTENT",
template: "simple_below_search_snippet",
content: {
icon: TEST_ICON,
icon_dark_theme: TEST_ICON_BW,
button_label: "Find Out Now",
button_url: "https://www.mozilla.org/en-US/firefox/accounts",
title: "See if you've been part of an online data breach.",
text:
"Firefox Monitor tells you what hackers already know about you. Here's some extra text to make the content really long.",
block_button_text: "Block",
},
},
{
id: "SPECIAL_SNIPPET_NO_TITLE",
template: "simple_below_search_snippet",
content: {
icon: TEST_ICON,
icon_dark_theme: TEST_ICON_BW,
button_label: "Find Out Now",
button_url: "https://www.mozilla.org/en-US/firefox/accounts",
text: "Firefox Monitor tells you what hackers already know about you.",
block_button_text: "Block",
},
},
{
id: "SPECIAL_SNIPPET_MONITOR",
template: "simple_below_search_snippet",

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

@ -1925,7 +1925,6 @@ describe("ASRouter", () => {
it("should add/remove observers for `webextension-install-notify`", async () => {
sandbox.spy(global.Services.obs, "addObserver");
sandbox.spy(global.Services.obs, "removeObserver");
sandbox.spy(Router, "blockMessageById");
sandbox.stub(MessageLoaderUtils, "installAddonFromURL").resolves(null);
const msg = fakeExecuteUserAction({
@ -1943,8 +1942,6 @@ describe("ASRouter", () => {
assert.calledOnce(global.Services.obs.removeObserver);
assert.calledOnce(channel.sendAsyncMessage);
assert.calledOnce(Router.blockMessageById);
assert.calledWithExactly(Router.blockMessageById, "RETURN_TO_AMO_1");
});
});

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

@ -213,6 +213,13 @@ describe("<FirstRun>", () => {
);
});
it("should hide the interrupt when props.interruptCleared changes to true", () => {
assert.lengthOf(wrapper.find(Interrupt), 1, "Interrupt shown");
wrapper.setProps({ interruptCleared: true });
assert.lengthOf(wrapper.find(Interrupt), 0, "Interrupt hidden");
});
it("should hide triplets when closeTriplets is called and block extended triplets after 500ms", () => {
// Simulate calling next scene
wrapper

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

@ -1,12 +1,18 @@
import {
DSCard,
DefaultMeta,
PlaceholderDSCard,
VariantMeta,
} from "content-src/components/DiscoveryStreamComponents/DSCard/DSCard";
import {
DSContextFooter,
StatusMessage,
} from "content-src/components/DiscoveryStreamComponents/DSContextFooter/DSContextFooter";
import { actionCreators as ac } from "common/Actions.jsm";
import { DSLinkMenu } from "content-src/components/DiscoveryStreamComponents/DSLinkMenu/DSLinkMenu";
import React from "react";
import { SafeAnchor } from "content-src/components/DiscoveryStreamComponents/SafeAnchor/SafeAnchor";
import { shallow } from "enzyme";
import { shallow, mount } from "enzyme";
describe("<DSCard>", () => {
let wrapper;
@ -71,6 +77,22 @@ describe("<DSCard>", () => {
assert.equal(wrapper.find(".active").length, 0);
});
it("should render badges for pocket, bookmark when not a spoc element ", () => {
wrapper = mount(<DSCard context_type="bookmark" />);
const contextFooter = wrapper.find(DSContextFooter);
assert.lengthOf(contextFooter.find(StatusMessage), 1);
});
it("should render Sponsored Context for a spoc element", () => {
const context = "Sponsored by Foo";
wrapper = mount(<DSCard context_type="bookmark" context={context} />);
const contextFooter = wrapper.find(DSContextFooter);
assert.lengthOf(contextFooter.find(StatusMessage), 0);
assert.equal(contextFooter.find(".story-sponsored-label").text(), context);
});
describe("onLinkClick", () => {
let dispatch;
@ -134,6 +156,57 @@ describe("<DSCard>", () => {
);
});
});
describe("DSCard with CTA", () => {
beforeEach(() => {
wrapper = mount(<DSCard />);
});
it("should render Default Meta", () => {
const default_meta = wrapper.find(DefaultMeta);
assert.ok(default_meta.exists());
});
it("should not render cta-link for item with no cta", () => {
const meta = wrapper.find(DefaultMeta);
assert.notOk(meta.find(".cta-link").exists());
});
it("should render cta-link by default when item has cta", () => {
wrapper.setProps({ cta: "test" });
const meta = wrapper.find(DefaultMeta);
assert.equal(meta.find(".cta-link").text(), "test");
});
it("should render cta-button when item has cta and cta button variant is true", () => {
wrapper.setProps({ cta: "test", cta_variant: true });
const meta = wrapper.find(VariantMeta);
assert.equal(meta.find(".cta-button").text(), "test");
});
it("should not render Sponsored by label in footer for spoc item with cta button variant", () => {
wrapper.setProps({
cta: "test",
context: "Sponsored by test",
cta_variant: true,
});
assert.ok(wrapper.find(VariantMeta).exists());
assert.notOk(wrapper.find(DSContextFooter).exists());
});
it("should render sponsor text on top for spoc item and cta_variant true", () => {
wrapper.setProps({
sponsor: "Test",
context: "Sponsored by test",
cta_variant: true,
});
assert.ok(wrapper.find(VariantMeta).exists());
const meta = wrapper.find(VariantMeta);
assert.equal(meta.find(".source").text(), "Test · Sponsored");
});
});
});
describe("<PlaceholderDSCard> component", () => {

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

@ -1,4 +1,7 @@
import { DSContextFooter } from "content-src/components/DiscoveryStreamComponents/DSContextFooter/DSContextFooter";
import {
DSContextFooter,
StatusMessage,
} from "content-src/components/DiscoveryStreamComponents/DSContextFooter/DSContextFooter";
import React from "react";
import { mount } from "enzyme";
import { cardContextTypes } from "content-src/components/Card/types.js";
@ -8,6 +11,7 @@ describe("<DSContextFooter>", () => {
let sandbox;
const bookmarkBadge = "bookmark";
const removeBookmarkBadge = "removedBookmark";
const context = "Sponsored by Babel";
beforeEach(() => {
wrapper = mount(<DSContextFooter />);
@ -32,14 +36,11 @@ describe("<DSContextFooter>", () => {
});
it("should only render a sponsored context if pass a sponsored context", async () => {
wrapper = mount(
<DSContextFooter
context_type={bookmarkBadge}
context="Sponsored by Babel"
/>
<DSContextFooter context_type={bookmarkBadge} context={context} />
);
assert.isFalse(wrapper.find(".status-message").exists());
assert.isTrue(wrapper.find(".story-sponsored-label").exists());
assert.lengthOf(wrapper.find(StatusMessage), 0);
assert.equal(wrapper.find(".story-sponsored-label").text(), context);
});
it("should render a new badge if props change from an old badge to a new one", async () => {
wrapper = mount(<DSContextFooter context_type={bookmarkBadge} />);

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

@ -2,6 +2,10 @@ import {
DSCard,
PlaceholderDSCard,
} from "content-src/components/DiscoveryStreamComponents/DSCard/DSCard";
import {
DSContextFooter,
StatusMessage,
} from "content-src/components/DiscoveryStreamComponents/DSContextFooter/DSContextFooter";
import { actionCreators as ac } from "common/Actions.jsm";
import { DSEmptyState } from "content-src/components/DiscoveryStreamComponents/DSEmptyState/DSEmptyState";
import { Hero } from "content-src/components/DiscoveryStreamComponents/Hero/Hero";
@ -51,6 +55,36 @@ describe("<Hero>", () => {
);
});
it("should render badges for pocket, bookmark when not a spoc element ", () => {
const heroProps = {
data: { recommendations: [{ context_type: "bookmark" }] },
header: { title: "headerTitle" },
};
const wrapper = shallow(<Hero {...heroProps} />);
const contextFooter = wrapper.find(DSContextFooter).shallow();
assert.lengthOf(contextFooter.find(StatusMessage), 1);
});
it("should render Sponsored Context for a spoc element", () => {
const heroProps = {
data: {
recommendations: [
{ context_type: "bookmark", context: "Sponsored by Foo" },
],
},
header: { title: "headerTitle" },
};
const wrapper = shallow(<Hero {...heroProps} />);
const contextFooter = wrapper.find(DSContextFooter).shallow();
assert.lengthOf(contextFooter.find(StatusMessage), 0);
assert.equal(
contextFooter.find(".story-sponsored-label").text(),
heroProps.data.recommendations[0].context
);
});
describe("subComponent: cards", () => {
beforeEach(() => {
DEFAULT_PROPS.subComponentType = "cards";

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

@ -4,6 +4,10 @@ import {
PlaceholderListItem,
} from "content-src/components/DiscoveryStreamComponents/List/List";
import { actionCreators as ac } from "common/Actions.jsm";
import {
DSContextFooter,
StatusMessage,
} from "content-src/components/DiscoveryStreamComponents/DSContextFooter/DSContextFooter";
import { DSEmptyState } from "content-src/components/DiscoveryStreamComponents/DSEmptyState/DSEmptyState";
import { DSLinkMenu } from "content-src/components/DiscoveryStreamComponents/DSLinkMenu/DSLinkMenu";
import { GlobalOverrider } from "test/unit/utils";
@ -125,12 +129,14 @@ describe("<ListItem> presentation component", () => {
title: "FAKE_TITLE",
domain: "example.com",
image_src: "FAKE_IMAGE_SRC",
context_type: "pocket",
};
const ValidLSpocListItemProps = {
const ValidSpocListItemProps = {
url: "FAKE_URL",
title: "FAKE_TITLE",
domain: "example.com",
image_src: "FAKE_IMAGE_SRC",
context_type: "pocket",
context: "FAKE_CONTEXT",
};
let globals;
@ -152,18 +158,22 @@ describe("<ListItem> presentation component", () => {
assert.lengthOf(anchors, 1);
});
it("should not contain 'span.ds-list-item-context' without props.context", () => {
it("should render badges for pocket, bookmark when not a spoc element ", () => {
const wrapper = shallow(<ListItem {...ValidListItemProps} />);
const contextFooter = wrapper.find(DSContextFooter).shallow();
const contextEl = wrapper.find("span.ds-list-item-context");
assert.lengthOf(contextEl, 0);
assert.lengthOf(contextFooter.find(StatusMessage), 1);
});
it("should contain 'span.ds-list-item-context' spoc element", () => {
const wrapper = shallow(<ListItem {...ValidLSpocListItemProps} />);
it("should render Sponsored Context for a spoc element", () => {
const wrapper = shallow(<ListItem {...ValidSpocListItemProps} />);
const contextFooter = wrapper.find(DSContextFooter).shallow();
const contextEl = wrapper.find("span.ds-list-item-context");
assert.lengthOf(contextEl, 1);
assert.lengthOf(contextFooter.find(StatusMessage), 0);
assert.equal(
contextFooter.find(".story-sponsored-label").text(),
ValidSpocListItemProps.context
);
});
describe("onLinkClick", () => {