Bug 1533832 - Add CFR Pin Tab, Discovery dark theme and bug fixes to Activity Stream r=k88hudson

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ed Lee 2019-03-08 21:37:36 +00:00
Родитель 8062e8e8b0
Коммит 8a863cd832
46 изменённых файлов: 1953 добавлений и 749 удалений

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

@ -15,6 +15,10 @@
}
},
"properties": {
"category": {
"type": "string",
"description": "Attribute used for different groups of messages from the same provider"
},
"bucket_id": {
"type": "string",
"description": "A bucket identifier for the addon. This is used in order to anonymize telemetry for history-sensitive targeting."
@ -166,6 +170,27 @@
}
]
},
"descriptionDetails": {
"description": "Additional information and steps on how to use",
"type": "object",
"properties": {
"steps": {
"description": "Array of messages or string_ids",
"type": "array",
"items": {
"type": "object",
"properties": {
"string_id": {
"type": "string",
"description": "Id of string to localized addon description"
}
},
"required": ["string_id"]
}
}
},
"required": ["steps"]
},
"buttons": {
"description": "The label and functionality for the buttons in the pop-over.",
"type": "object",
@ -299,5 +324,5 @@
}
},
"additionalProperties": false,
"required": ["bucket_id", "notification_text", "heading_text", "text", "buttons"]
"required": ["category", "bucket_id", "notification_text", "heading_text", "text", "buttons"]
}

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

@ -76,6 +76,12 @@
"type": "string",
"description": "Snippet icon. 64x64px. SVG or PNG preferred."
},
"title": {
"allOf": [
{"$ref": "#/definitions/plainText"},
{"description": "Snippet title displayed before snippet text"}
]
},
"title_icon": {
"type": "string",
"description": "Small icon that shows up before the title / text. 16x16px. SVG or PNG preferred. Grayscale."

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

@ -137,15 +137,6 @@ export class BaseContent extends React.PureComponent {
this.props.dispatch(ac.UserEvent({event: "OPEN_NEWTAB_PREFS"}));
}
disableDarkTheme() {
// Dark themes are not supported in discovery stream view
// Add force-light-theme class to body tag to disable dark mode. See Bug 1519764
const bodyClassNames = global.document.body.classList;
if (!bodyClassNames.contains("force-light-theme")) {
bodyClassNames.add("force-light-theme");
}
}
render() {
const {props} = this;
const {App} = props;
@ -157,10 +148,6 @@ export class BaseContent extends React.PureComponent {
const isDiscoveryStream = props.DiscoveryStream.config && props.DiscoveryStream.config.enabled;
const searchHandoffEnabled = prefs["improvesearch.handoffToAwesomebar"];
if (isDiscoveryStream) {
this.disableDarkTheme();
}
const outerClassName = [
"outer-wrapper",
isDiscoveryStream && "ds-outer-wrapper-search-alignment",

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

@ -4,6 +4,7 @@ export class ContextMenu extends React.PureComponent {
constructor(props) {
super(props);
this.hideContext = this.hideContext.bind(this);
this.onShow = this.onShow.bind(this);
this.onClick = this.onClick.bind(this);
}
@ -11,7 +12,14 @@ export class ContextMenu extends React.PureComponent {
this.props.onUpdate(false);
}
onShow() {
if (this.props.onShow) {
this.props.onShow();
}
}
componentDidMount() {
this.onShow();
setTimeout(() => {
global.addEventListener("click", this.hideContext);
}, 0);

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

@ -25,6 +25,10 @@
}
.ds-header {
@include dark-theme-only {
color: $grey-30;
}
color: $grey-50;
font-size: 13px;
font-weight: 600;

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

@ -7,16 +7,29 @@ $col4-header-font-size: 14;
margin: 16px 0;
.ds-card {
@include dark-theme-only {
background: none;
}
background: $white;
border-radius: 4px;
}
&.ds-card-grid-border {
.ds-card {
box-shadow: var(--newtab-card-shadow);
@include dark-theme-only {
box-shadow: 0 1px 4px $shadow-10;
background: $grey-70;
}
box-shadow: 0 1px 4px 0 $grey-90-10;
&:hover {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
@include dark-theme-only {
box-shadow: 0 0 0 5px $grey-60;
}
box-shadow: 0 0 0 5px $grey-30;
transition: box-shadow 150ms;
outline: none;
}

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

@ -1,4 +1,5 @@
import {actionCreators as ac} from "common/Actions.jsm";
import {DSLinkMenu} from "../DSLinkMenu/DSLinkMenu";
import {ImpressionStats} from "../../DiscoveryStreamImpressionStats/ImpressionStats";
import React from "react";
import {SafeAnchor} from "../SafeAnchor/SafeAnchor";
@ -28,35 +29,45 @@ export class DSCard extends React.PureComponent {
render() {
return (
<SafeAnchor
className="ds-card"
dispatch={this.props.dispatch}
onLinkClick={this.onLinkClick}
url={this.props.url}>
<div className="img-wrapper">
<div className="img" style={{backgroundImage: `url(${this.props.image_src}`}} />
</div>
<div className="meta">
<div className="info-wrap">
<header className="title">{this.props.title}</header>
{this.props.excerpt && <p className="excerpt">{this.props.excerpt}</p>}
</div>
<p>
{this.props.context && (
<span>
<span className="context">{this.props.context}</span>
<br />
</span>
)}
<span className="source">{this.props.source}</span>
</p>
</div>
<ImpressionStats
campaignId={this.props.campaignId}
rows={[{id: this.props.id, pos: this.props.pos}]}
<div className="ds-card">
<SafeAnchor
className="ds-card-link"
dispatch={this.props.dispatch}
source={this.props.type} />
</SafeAnchor>
onLinkClick={this.onLinkClick}
url={this.props.url}>
<div className="img-wrapper">
<div className="img" style={{backgroundImage: `url(${this.props.image_src}`}} />
</div>
<div className="meta">
<div className="info-wrap">
<header className="title">{this.props.title}</header>
{this.props.excerpt && <p className="excerpt">{this.props.excerpt}</p>}
</div>
<p>
{this.props.context && (
<span>
<span className="context">{this.props.context}</span>
<br />
</span>
)}
<span className="source">{this.props.source}</span>
</p>
</div>
<ImpressionStats
campaignId={this.props.campaignId}
rows={[{id: this.props.id, pos: this.props.pos}]}
dispatch={this.props.dispatch}
source={this.props.type} />
</SafeAnchor>
<DSLinkMenu
index={this.props.index}
dispatch={this.props.dispatch}
intl={this.props.intl}
url={this.props.url}
title={this.props.title}
source={this.props.source}
type={this.props.type} />
</div>
);
}
}

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

@ -11,6 +11,10 @@ $excerpt-line-height: 20;
&:hover {
header {
@include dark-theme-only {
color: $blue-40;
}
color: $blue-60;
}
}
@ -31,6 +35,13 @@ $excerpt-line-height: 20;
padding-top: 50%; // 2:1 aspect ratio
}
.ds-card-link {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
}
.meta {
display: flex;
flex-direction: column;
@ -54,19 +65,30 @@ $excerpt-line-height: 20;
.context,
.source {
@include dark-theme-only {
color: $teal-10;
}
font-size: 13px;
color: $teal-80;
}
}
header {
@include dark-theme-only {
color: $grey-10;
}
line-height: $header-line-height * 1px;
font-size: $header-font-size * 1px;
color: $grey-90;
}
p {
@include dark-theme-only {
color: $grey-30;
}
font-size: $excerpt-font-size * 1px;
line-height: $excerpt-line-height * 1px;
color: $grey-50;

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

@ -0,0 +1,77 @@
import {FormattedMessage, injectIntl} from "react-intl";
import {LinkMenu} from "content-src/components/LinkMenu/LinkMenu";
import React from "react";
export class _DSLinkMenu extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
activeCard: null,
showContextMenu: false,
};
this.onMenuButtonClick = this.onMenuButtonClick.bind(this);
this.onMenuUpdate = this.onMenuUpdate.bind(this);
this.onMenuShow = this.onMenuShow.bind(this);
this.contextMenuButtonRef = React.createRef();
}
onMenuButtonClick(event) {
event.preventDefault();
this.setState({
activeCard: this.props.index,
showContextMenu: true,
});
}
onMenuUpdate(showContextMenu) {
if (!showContextMenu) {
const dsLinkMenuHostDiv = this.contextMenuButtonRef.current.parentElement;
dsLinkMenuHostDiv.parentElement.classList.remove("active", "last-item");
}
this.setState({showContextMenu});
}
onMenuShow() {
const dsLinkMenuHostDiv = this.contextMenuButtonRef.current.parentElement;
if (window.scrollMaxX > 0) {
dsLinkMenuHostDiv.parentElement.classList.add("last-item");
}
dsLinkMenuHostDiv.parentElement.classList.add("active");
}
render() {
const {index, dispatch} = this.props;
const isContextMenuOpen = this.state.showContextMenu && this.state.activeCard === index;
const TOP_STORIES_SOURCE = "TOP_STORIES";
const TOP_STORIES_CONTEXT_MENU_OPTIONS = ["OpenInNewWindow", "OpenInPrivateWindow"];
const title = this.props.title || this.props.source;
return (<div>
<button ref={this.contextMenuButtonRef}
className="context-menu-button icon"
title={this.props.intl.formatMessage({id: "context_menu_title"})}
onClick={this.onMenuButtonClick}>
<span className="sr-only">
<FormattedMessage id="context_menu_button_sr" values={{title}} />
</span>
</button>
{isContextMenuOpen &&
<LinkMenu
dispatch={dispatch}
index={index}
source={TOP_STORIES_SOURCE}
onUpdate={this.onMenuUpdate}
onShow={this.onMenuShow}
options={TOP_STORIES_CONTEXT_MENU_OPTIONS}
site={{
referrer: "https://getpocket.com/recommendations",
title: this.props.title,
type: this.props.type,
url: this.props.url,
}} />
}
</div>);
}
}
export const DSLinkMenu = injectIntl(_DSLinkMenu);

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

@ -0,0 +1,32 @@
.ds-hero-item,
.ds-list-item,
.ds-card {
@include context-menu-button;
.context-menu {
opacity: 0;
}
&.active {
.context-menu {
opacity: 1;
}
}
&.last-item {
@include context-menu-open-left;
.context-menu {
opacity: 1;
}
}
&:-moz-any(:hover, :focus, .active) {
@include context-menu-button-hover;
outline: none;
&.ds-card-grid-border {
@include fade-in-card;
}
}
}

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

@ -6,17 +6,25 @@
align-items: center;
.glyph {
@include dark-theme-only {
fill: $grey-30;
}
width: 16px;
height: 16px;
margin: 0 6px 0 0;
-moz-context-properties: fill;
fill: var(--newtab-icon-secondary-color);
fill: $grey-50;
background-position: center center;
background-size: 16px;
background-repeat: no-repeat;
}
.title-text {
@include dark-theme-only {
color: $grey-30;
}
line-height: 20px;
font-size: 13px;
color: $grey-50;

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

@ -1,5 +1,6 @@
import {actionCreators as ac} from "common/Actions.jsm";
import {DSCard} from "../DSCard/DSCard.jsx";
import {DSLinkMenu} from "../DSLinkMenu/DSLinkMenu";
import {ImpressionStats} from "../../DiscoveryStreamImpressionStats/ImpressionStats";
import {List} from "../List/List.jsx";
import React from "react";
@ -69,31 +70,41 @@ export class Hero extends React.PureComponent {
<div>
<div className="ds-header">{this.props.title}</div>
<div className={`ds-hero ds-hero-${this.props.border}`}>
<SafeAnchor
className="wrapper"
dispatch={this.props.dispatch}
onLinkClick={this.onLinkClick}
url={heroRec.url}>
<div className="img-wrapper">
<div className="img" style={{backgroundImage: `url(${heroRec.image_src})`}} />
</div>
<div className="meta">
<div className="header-and-excerpt">
<header>{heroRec.title}</header>
<p className="excerpt">{heroRec.excerpt}</p>
</div>
{heroRec.context ? (
<p className="context">{heroRec.context}</p>
) : (
<p className="source">{heroRec.domain}</p>
)}
</div>
<ImpressionStats
campaignId={heroRec.campaignId}
rows={[{id: heroRec.id, pos: heroRec.pos}]}
<div className="ds-hero-item">
<SafeAnchor
className="wrapper"
dispatch={this.props.dispatch}
source={this.props.type} />
</SafeAnchor>
onLinkClick={this.onLinkClick}
url={heroRec.url}>
<div className="img-wrapper">
<div className="img" style={{backgroundImage: `url(${heroRec.image_src})`}} />
</div>
<div className="meta">
<div className="header-and-excerpt">
<header>{heroRec.title}</header>
<p className="excerpt">{heroRec.excerpt}</p>
</div>
{heroRec.context ? (
<p className="context">{heroRec.context}</p>
) : (
<p className="source">{heroRec.domain}</p>
)}
</div>
<ImpressionStats
campaignId={heroRec.campaignId}
rows={[{id: heroRec.id, pos: heroRec.pos}]}
dispatch={this.props.dispatch}
source={this.props.type} />
</SafeAnchor>
<DSLinkMenu
index={this.props.index}
dispatch={this.props.dispatch}
intl={this.props.intl}
url={heroRec.url}
title={heroRec.title}
source={heroRec.domain}
type={this.props.type} />
</div>
<div className={`${this.props.subComponentType}`}>
{ this.props.subComponentType === `cards` ? cards : list }
</div>

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

@ -54,14 +54,23 @@ $card-header-in-hero-line-height: 20;
margin: 0 0 12px;
}
.ds-hero-item {
position: relative;
}
// "1/3 width layout" (aka "Mobile First")
.wrapper {
@include ds-border-top;
@include ds-border-bottom;
@include dark-theme-only {
color: $grey-30;
}
color: $grey-50;
display: block;
margin: 12px 0 16px;
padding: 16px 0;
border-top: $border-secondary;
border-bottom: $border-secondary;
height: 100%;
@at-root .ds-hero-no-border .wrapper {
border-top: 0;
@ -70,10 +79,18 @@ $card-header-in-hero-line-height: 20;
}
&:hover .meta header {
@include dark-theme-only {
color: $blue-40;
}
color: $blue-60;
}
&:active .meta header {
@include dark-theme-only {
color: $blue-40;
}
color: $blue-70;
}
@ -92,16 +109,28 @@ $card-header-in-hero-line-height: 20;
justify-content: space-between;
header {
@include dark-theme-only {
color: $white;
}
@include limit-visibile-lines(4, 28, 22);
color: $grey-90;
margin-bottom: 8px;
}
.context {
@include dark-theme-only {
color: $teal-10;
}
color: $teal-70;
}
.source {
@include dark-theme-only {
color: $teal-10;
}
font-size: 13px;
color: $teal-80;
margin-bottom: 0;
@ -156,11 +185,11 @@ $card-header-in-hero-line-height: 20;
grid-column-gap: 24px;
&.ds-hero-border {
border-top: $border-secondary;
@include ds-border-top;
padding: 20px 0;
.ds-card:nth-child(-n+2) {
border-bottom: $border-secondary;
@include ds-border-bottom;
margin-bottom: 20px;
}
}
@ -203,8 +232,30 @@ $card-header-in-hero-line-height: 20;
grid-template-columns: repeat(2, 1fr);
grid-column-gap: 24px;
.title {
@include limit-visibile-lines(3, 20, 14);
.ds-card {
&:hover {
@include dark-theme-only {
background: none;
.title {
color: $blue-40;
}
}
}
&:active .title {
@include dark-theme-only {
color: $blue-50;
}
}
.title {
@include dark-theme-only {
color: $white;
}
@include limit-visibile-lines(3, 20, 14);
}
}
}
}

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

@ -1,5 +1,7 @@
.ds-hr {
border: 0;
@include ds-border-top {
border: 0;
};
height: 0;
border-top: $border-secondary;
}

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

@ -1,5 +1,6 @@
import {actionCreators as ac} from "common/Actions.jsm";
import {connect} from "react-redux";
import {DSLinkMenu} from "../DSLinkMenu/DSLinkMenu";
import {ImpressionStats} from "../../DiscoveryStreamImpressionStats/ImpressionStats";
import React from "react";
import {SafeAnchor} from "../SafeAnchor/SafeAnchor";
@ -61,6 +62,14 @@ export class ListItem extends React.PureComponent {
dispatch={this.props.dispatch}
source={this.props.type} />
</SafeAnchor>
<DSLinkMenu
index={this.props.index}
dispatch={this.props.dispatch}
intl={this.props.intl}
url={this.props.url}
title={this.props.title}
source={this.props.source}
type={this.props.type} />
</li>
);
}

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

@ -10,7 +10,7 @@ $item-line-height: 20;
// set up, which means that some refactoring will be required to do this.
@mixin bottom-border-except-last-grid-row($columns) {
.ds-list-item:not(:nth-last-child(-n+#{$columns})) {
border-bottom: $border-secondary;
@include ds-border-bottom;
margin-bottom: -1px; // cancel out the pixel we used for the border
padding-bottom: $bordered-spacing;
}
@ -74,7 +74,10 @@ $item-line-height: 20;
}
a {
// XXX note that this only looks right in the light theme
@include dark-theme-only {
color: $grey-10;
}
color: $grey-90;
}
}
@ -92,7 +95,11 @@ $item-line-height: 20;
padding-inline-start: $counter-padded-size;
&::before {
background-color: var(--newtab-link-secondary-color);
@include dark-theme-only {
background-color: $teal-70;
}
background-color: $pocket-teal;
border-radius: $counter-size;
color: $white;
content: counter(list);
@ -107,17 +114,25 @@ $item-line-height: 20;
}
&:hover::before {
background-color: var(--newtab-link-primary-color);
@include dark-theme-only {
background-color: $blue-40;
}
background-color: $blue-40;
}
&:active::before {
@include dark-theme-only {
background-color: $blue-60;
}
background-color: $blue-70;
}
}
}
.ds-list-borders {
border-top: $border-secondary;
@include ds-border-top;
grid-row-gap: $bordered-spacing;
padding-top: $bordered-spacing;
@ -168,7 +183,7 @@ $item-line-height: 20;
.ds-list-item-excerpt {
@include limit-visibile-lines(2, $item-line-height, $item-font-size);
color: var(--newtab-text-secondary-color);
color: $grey-10-80;
margin: 4px 0 8px;
}
@ -181,6 +196,10 @@ $item-line-height: 20;
.ds-list-item-info,
.ds-list-item-context {
@include limit-visibile-lines(1, $item-line-height, $item-font-size);
@include dark-theme-only {
color: $teal-10;
}
color: $teal-80;
font-size: 13px;
text-overflow: ellipsis;
@ -206,7 +225,7 @@ $item-line-height: 20;
&:hover {
.ds-list-item-title {
color: var(--newtab-link-primary-color);
color: $blue-40;
}
}

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

@ -33,7 +33,7 @@
a {
&:hover {
// text-decoration: underline; didn't quite match comps.
border-bottom: 1px solid var(--newtab-link-primary-color);
border-bottom: 1px solid $blue-40;
&:active {
border-bottom: 1px solid $blue-70;

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

@ -3,6 +3,10 @@
margin-top: 24px;
.title {
@include dark-theme-only {
color: $white;
}
line-height: 48px;
font-size: 36px;
font-weight: 300;
@ -10,6 +14,10 @@
}
.subtitle {
@include dark-theme-only {
color: $grey-30;
}
line-height: 24px;
font-size: 14px;
color: $grey-50;

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

@ -48,6 +48,7 @@ export class _LinkMenu extends React.PureComponent {
render() {
return (<ContextMenu
onUpdate={this.props.onUpdate}
onShow={this.props.onShow}
options={this.getOptions()} />);
}
}

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

@ -155,6 +155,7 @@ input {
@import '../components/DiscoveryStreamComponents/Navigation/Navigation';
@import '../components/DiscoveryStreamComponents/SectionTitle/SectionTitle';
@import '../components/DiscoveryStreamComponents/TopSites/TopSites';
@import '../components/DiscoveryStreamComponents/DSLinkMenu/DSLinkMenu';
@import '../components/DiscoveryStreamComponents/DSCard/DSCard';
@import '../components/DiscoveryStreamComponents/DSMessage/DSMessage';
@import '../components/DiscoveryStreamImpressionStats/ImpressionStats';

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

@ -15,3 +15,29 @@
max-height: 1em * $line-count * $line-height / $font-size;
overflow: hidden;
}
@mixin dark-theme-only {
[lwt-newtab-brighttext]:not(.force-light-theme) & {
@content;
}
}
@mixin ds-border-top {
@content;
@include dark-theme-only {
border-top: 1px solid $grey-60;
}
border-top: 1px solid $grey-30;
}
@mixin ds-border-bottom {
@content;
@include dark-theme-only {
border-bottom: 1px solid $grey-60;
}
border-bottom: 1px solid $grey-30;
}

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

@ -13,6 +13,8 @@ $grey-60: #4A4A4F;
$grey-70: #38383D;
$grey-80: #2A2A2E;
$grey-90: #0C0C0D;
$teal-10: #A7FFFE;
$teal-60: #00C8D7;
$teal-70: #008EA4;
$teal-80: #005A71;
$red-60: #D70022;
@ -57,6 +59,7 @@ $white: #FFF;
$white-10: rgba($white, 0.1);
$pocket-teal: #50BCB6;
$pocket-red: #EF4056;
$shadow-10: rgba(12, 12, 13, 0.1);
$bookmark-icon-fill: #0A84FF;
$download-icon-fill: #12BC00;
$pocket-icon-fill: #D70022;

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

@ -1842,6 +1842,8 @@ main {
font-weight: 600;
line-height: 20px;
margin: 8px 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-header {
color: #D7D7DB; }
.ds-header .icon {
fill: var(--newtab-text-secondary-color); }
@ -1885,12 +1887,19 @@ main {
.ds-card-grid .ds-card {
background: #FFF;
border-radius: 4px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card-grid .ds-card {
background: none; }
.ds-card-grid.ds-card-grid-border .ds-card {
box-shadow: var(--newtab-card-shadow); }
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1); }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card-grid.ds-card-grid-border .ds-card {
box-shadow: 0 1px 4px rgba(12, 12, 13, 0.1);
background: #38383D; }
.ds-card-grid.ds-card-grid-border .ds-card:hover {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
box-shadow: 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms;
outline: none; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card-grid.ds-card-grid-border .ds-card:hover {
box-shadow: 0 0 0 5px #4A4A4F; }
.ds-card-grid.ds-card-grid-border .ds-card .img-wrapper .img {
border-radius: 4px 4px 0 0; }
.ds-card-grid.ds-card-grid-no-border .ds-card {
@ -1965,21 +1974,34 @@ main {
margin: 0 0 12px; }
.ds-hero .img-wrapper {
margin: 0 0 12px; }
.ds-hero .ds-hero-item {
position: relative; }
.ds-hero .wrapper {
border-top: 1px solid #D7D7DB;
border-bottom: 1px solid #D7D7DB;
color: #737373;
display: block;
margin: 12px 0 16px;
padding: 16px 0;
border-top: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid var(--newtab-border-secondary-color); }
height: 100%; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper {
border-top: 1px solid #4A4A4F; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper {
border-bottom: 1px solid #4A4A4F; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper {
color: #D7D7DB; }
.ds-hero-no-border .wrapper {
border-top: 0;
border-bottom: 0;
padding: 0 0 8px; }
.ds-hero .wrapper:hover .meta header {
color: #0060DF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper:hover .meta header {
color: #45A1FF; }
.ds-hero .wrapper:active .meta header {
color: #003EAA; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper:active .meta header {
color: #45A1FF; }
.ds-hero .wrapper .img-wrapper {
width: 100%; }
.ds-hero .wrapper .img {
@ -1996,14 +2018,20 @@ main {
overflow: hidden;
color: #0C0C0D;
margin-bottom: 8px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper .meta header {
color: #FFF; }
.ds-hero .wrapper .meta .context {
color: #008EA4; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper .meta .context {
color: #A7FFFE; }
.ds-hero .wrapper .meta .source {
font-size: 13px;
color: #005A71;
margin-bottom: 0;
overflow-x: hidden;
text-overflow: ellipsis; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper .meta .source {
color: #A7FFFE; }
.ds-column-5 .ds-hero .wrapper,
.ds-column-6 .ds-hero .wrapper,
.ds-column-7 .ds-hero .wrapper,
@ -2049,14 +2077,24 @@ main {
.ds-column-10 .ds-hero.ds-hero-border,
.ds-column-11 .ds-hero.ds-hero-border,
.ds-column-12 .ds-hero.ds-hero-border {
border-top: 1px solid var(--newtab-border-secondary-color);
border-top: 1px solid #D7D7DB;
padding: 20px 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero.ds-hero-border, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero.ds-hero-border, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero.ds-hero-border, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero.ds-hero-border {
border-top: 1px solid #4A4A4F; }
.ds-column-9 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2),
.ds-column-10 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2),
.ds-column-11 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2),
.ds-column-12 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: 20px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2) {
border-bottom: 1px solid #4A4A4F; }
.ds-column-9 .ds-hero .wrapper,
.ds-column-10 .ds-hero .wrapper,
.ds-column-11 .ds-hero .wrapper,
@ -2106,19 +2144,41 @@ main {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-column-gap: 24px; }
.ds-column-9 .ds-hero .cards .title,
.ds-column-10 .ds-hero .cards .title,
.ds-column-11 .ds-hero .cards .title,
.ds-column-12 .ds-hero .cards .title {
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card:hover, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card:hover, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card:hover, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card:hover {
background: none; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card:hover .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card:hover .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card:hover .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card:hover .title {
color: #45A1FF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card:active .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card:active .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card:active .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card:active .title {
color: #0A84FF; }
.ds-column-9 .ds-hero .cards .ds-card .title,
.ds-column-10 .ds-hero .cards .ds-card .title,
.ds-column-11 .ds-hero .cards .ds-card .title,
.ds-column-12 .ds-hero .cards .ds-card .title {
font-size: 14px;
line-height: 20px;
max-height: 4.28571em;
overflow: hidden; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card .title {
color: #FFF; }
.ds-hr {
border: 0;
height: 0;
border-top: 1px solid var(--newtab-border-secondary-color); }
border-top: 1px solid #D7D7DB;
height: 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hr {
border-top: 1px solid #4A4A4F; }
.ds-list {
display: grid;
@ -2153,6 +2213,8 @@ main {
display: none; }
.ds-list a {
color: #0C0C0D; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list a {
color: #F9F9FA; }
.ds-list-numbers .ds-list-item {
counter-increment: list; }
@ -2160,7 +2222,7 @@ main {
.ds-list-numbers .ds-list-item-link {
padding-inline-start: 41px; }
.ds-list-numbers .ds-list-item-link::before {
background-color: var(--newtab-link-secondary-color);
background-color: #50BCB6;
border-radius: 32px;
color: #FFF;
content: counter(list);
@ -2172,37 +2234,61 @@ main {
position: absolute;
text-align: center;
width: 32px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-numbers .ds-list-item-link::before {
background-color: #008EA4; }
.ds-list-numbers .ds-list-item-link:hover::before {
background-color: var(--newtab-link-primary-color); }
background-color: #45A1FF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-numbers .ds-list-item-link:hover::before {
background-color: #45A1FF; }
.ds-list-numbers .ds-list-item-link:active::before {
background-color: #003EAA; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-numbers .ds-list-item-link:active::before {
background-color: #0060DF; }
.ds-list-borders {
border-top: 1px solid var(--newtab-border-secondary-color);
border-top: 1px solid #D7D7DB;
grid-row-gap: 16px;
padding-top: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-borders {
border-top: 1px solid #4A4A4F; }
.ds-list-borders.ds-list-full-width .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-1 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-2 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-3 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-4 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: -1px;
padding-bottom: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-borders.ds-list-full-width .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-1 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-2 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-3 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-4 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)) {
border-bottom: 1px solid #4A4A4F; }
.ds-column-5 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)),
.ds-column-6 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)),
.ds-column-7 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)),
.ds-column-8 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: -1px;
padding-bottom: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-5 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-6 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-7 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-8 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)) {
border-bottom: 1px solid #4A4A4F; }
.ds-column-9 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)),
.ds-column-10 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)),
.ds-column-11 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)),
.ds-column-12 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: -1px;
padding-bottom: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)) {
border-bottom: 1px solid #4A4A4F; }
.ds-list-full-width .ds-list-item {
font-size: 17px;
@ -2232,7 +2318,7 @@ main {
line-height: 20px;
max-height: 2.85714em;
overflow: hidden;
color: var(--newtab-text-secondary-color);
color: rgba(249, 249, 250, 0.8);
margin: 4px 0 8px; }
.ds-list-item p {
font-size: 14px;
@ -2247,6 +2333,9 @@ main {
color: #005A71;
font-size: 13px;
text-overflow: ellipsis; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-item .ds-list-item-info, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-list-item .ds-list-item-context {
color: #A7FFFE; }
.ds-list-item .ds-list-item-title {
font-weight: 600;
margin-bottom: 4px; }
@ -2265,7 +2354,7 @@ main {
margin-inline-start: 14px;
min-height: 80px; }
.ds-list-item:hover .ds-list-item-title {
color: var(--newtab-link-primary-color); }
color: #45A1FF; }
.ds-list-item:active .ds-list-item-title {
color: #003EAA; }
@ -2290,7 +2379,7 @@ main {
.ds-navigation ul li:last-child::after {
content: none; }
.ds-navigation ul li a:hover {
border-bottom: 1px solid var(--newtab-link-primary-color); }
border-bottom: 1px solid #45A1FF; }
.ds-navigation ul li a:hover:active {
border-bottom: 1px solid #003EAA; }
.ds-navigation ul li a:active {
@ -2306,11 +2395,15 @@ main {
font-size: 36px;
font-weight: 300;
color: #0C0C0D; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-section-title .title {
color: #FFF; }
.ds-section-title .subtitle {
line-height: 24px;
font-size: 14px;
color: #737373;
margin-top: 4px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-section-title .subtitle {
color: #D7D7DB; }
.ds-top-sites .ds-header-title {
vertical-align: middle; }
@ -2391,12 +2484,80 @@ main {
.ds-column-4 .ds-top-sites .top-site-inner .title {
width: var(--rightPanelIconWidth); }
.ds-hero-item .context-menu-button,
.ds-list-item .context-menu-button,
.ds-card .context-menu-button {
background-clip: padding-box;
background-color: var(--newtab-contextmenu-button-color);
background-image: url("chrome://browser/skin/page-action.svg");
background-position: 55%;
border: 1px solid var(--newtab-border-primary-color);
border-radius: 100%;
box-shadow: 0 2px rgba(12, 12, 13, 0.1);
cursor: pointer;
fill: var(--newtab-icon-primary-color);
height: 27px;
inset-inline-end: -13.5px;
opacity: 0;
position: absolute;
top: -13.5px;
transform: scale(0.25);
transition-duration: 150ms;
transition-property: transform, opacity;
width: 27px; }
.ds-hero-item .context-menu-button:-moz-any(:active, :focus),
.ds-list-item .context-menu-button:-moz-any(:active, :focus),
.ds-card .context-menu-button:-moz-any(:active, :focus) {
opacity: 1;
transform: scale(1); }
.ds-hero-item .context-menu,
.ds-list-item .context-menu,
.ds-card .context-menu {
opacity: 0; }
.ds-hero-item.active .context-menu,
.ds-list-item.active .context-menu,
.ds-card.active .context-menu {
opacity: 1; }
.ds-hero-item.last-item .context-menu,
.ds-list-item.last-item .context-menu,
.ds-card.last-item .context-menu {
margin-inline-end: 5px;
margin-inline-start: auto;
inset-inline-end: 0;
inset-inline-start: auto; }
.ds-hero-item.last-item .context-menu,
.ds-list-item.last-item .context-menu,
.ds-card.last-item .context-menu {
opacity: 1; }
.ds-hero-item:-moz-any(:hover, :focus, .active),
.ds-list-item:-moz-any(:hover, :focus, .active),
.ds-card:-moz-any(:hover, :focus, .active) {
outline: none; }
.ds-hero-item:-moz-any(:hover, :focus, .active) .context-menu-button,
.ds-list-item:-moz-any(:hover, :focus, .active) .context-menu-button,
.ds-card:-moz-any(:hover, :focus, .active) .context-menu-button {
opacity: 1;
transform: scale(1);
transition-delay: 333ms; }
.ds-hero-item:-moz-any(:hover, :focus, .active).ds-card-grid-border,
.ds-list-item:-moz-any(:hover, :focus, .active).ds-card-grid-border,
.ds-card:-moz-any(:hover, :focus, .active).ds-card-grid-border {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
transition: box-shadow 150ms; }
.ds-card {
display: flex;
flex-direction: column;
position: relative; }
.ds-card:hover header {
color: #0060DF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card:hover header {
color: #45A1FF; }
.ds-card:active header {
color: #003EAA; }
.ds-card .img-wrapper {
@ -2410,6 +2571,11 @@ main {
box-shadow: inset 0 0 0 0.5px rgba(0, 0, 0, 0.15);
height: 0;
padding-top: 50%; }
.ds-card .ds-card-link {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%; }
.ds-card .meta {
display: flex;
flex-direction: column;
@ -2432,15 +2598,22 @@ main {
.ds-card .meta .source {
font-size: 13px;
color: #005A71; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card .meta .context, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-card .meta .source {
color: #A7FFFE; }
.ds-card header {
line-height: 24px;
font-size: 17px;
color: #0C0C0D; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card header {
color: #F9F9FA; }
.ds-card p {
font-size: 14px;
line-height: 20px;
color: #737373;
margin: 8px 0 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card p {
color: #D7D7DB; }
.ds-message {
margin: 8px 0 0; }
@ -2452,16 +2625,20 @@ main {
height: 16px;
margin: 0 6px 0 0;
-moz-context-properties: fill;
fill: var(--newtab-icon-secondary-color);
fill: #737373;
background-position: center center;
background-size: 16px;
background-repeat: no-repeat; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-message .title .glyph {
fill: #D7D7DB; }
.ds-message .title .title-text {
line-height: 20px;
font-size: 13px;
color: #737373;
font-weight: 600;
padding-right: 12px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-message .title .title-text {
color: #D7D7DB; }
.ds-message .title .link {
line-height: 20px;
font-size: 13px; }

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

@ -1845,6 +1845,8 @@ main {
font-weight: 600;
line-height: 20px;
margin: 8px 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-header {
color: #D7D7DB; }
.ds-header .icon {
fill: var(--newtab-text-secondary-color); }
@ -1888,12 +1890,19 @@ main {
.ds-card-grid .ds-card {
background: #FFF;
border-radius: 4px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card-grid .ds-card {
background: none; }
.ds-card-grid.ds-card-grid-border .ds-card {
box-shadow: var(--newtab-card-shadow); }
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1); }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card-grid.ds-card-grid-border .ds-card {
box-shadow: 0 1px 4px rgba(12, 12, 13, 0.1);
background: #38383D; }
.ds-card-grid.ds-card-grid-border .ds-card:hover {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
box-shadow: 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms;
outline: none; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card-grid.ds-card-grid-border .ds-card:hover {
box-shadow: 0 0 0 5px #4A4A4F; }
.ds-card-grid.ds-card-grid-border .ds-card .img-wrapper .img {
border-radius: 4px 4px 0 0; }
.ds-card-grid.ds-card-grid-no-border .ds-card {
@ -1968,21 +1977,34 @@ main {
margin: 0 0 12px; }
.ds-hero .img-wrapper {
margin: 0 0 12px; }
.ds-hero .ds-hero-item {
position: relative; }
.ds-hero .wrapper {
border-top: 1px solid #D7D7DB;
border-bottom: 1px solid #D7D7DB;
color: #737373;
display: block;
margin: 12px 0 16px;
padding: 16px 0;
border-top: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid var(--newtab-border-secondary-color); }
height: 100%; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper {
border-top: 1px solid #4A4A4F; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper {
border-bottom: 1px solid #4A4A4F; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper {
color: #D7D7DB; }
.ds-hero-no-border .wrapper {
border-top: 0;
border-bottom: 0;
padding: 0 0 8px; }
.ds-hero .wrapper:hover .meta header {
color: #0060DF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper:hover .meta header {
color: #45A1FF; }
.ds-hero .wrapper:active .meta header {
color: #003EAA; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper:active .meta header {
color: #45A1FF; }
.ds-hero .wrapper .img-wrapper {
width: 100%; }
.ds-hero .wrapper .img {
@ -1999,14 +2021,20 @@ main {
overflow: hidden;
color: #0C0C0D;
margin-bottom: 8px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper .meta header {
color: #FFF; }
.ds-hero .wrapper .meta .context {
color: #008EA4; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper .meta .context {
color: #A7FFFE; }
.ds-hero .wrapper .meta .source {
font-size: 13px;
color: #005A71;
margin-bottom: 0;
overflow-x: hidden;
text-overflow: ellipsis; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper .meta .source {
color: #A7FFFE; }
.ds-column-5 .ds-hero .wrapper,
.ds-column-6 .ds-hero .wrapper,
.ds-column-7 .ds-hero .wrapper,
@ -2052,14 +2080,24 @@ main {
.ds-column-10 .ds-hero.ds-hero-border,
.ds-column-11 .ds-hero.ds-hero-border,
.ds-column-12 .ds-hero.ds-hero-border {
border-top: 1px solid var(--newtab-border-secondary-color);
border-top: 1px solid #D7D7DB;
padding: 20px 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero.ds-hero-border, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero.ds-hero-border, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero.ds-hero-border, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero.ds-hero-border {
border-top: 1px solid #4A4A4F; }
.ds-column-9 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2),
.ds-column-10 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2),
.ds-column-11 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2),
.ds-column-12 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: 20px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2) {
border-bottom: 1px solid #4A4A4F; }
.ds-column-9 .ds-hero .wrapper,
.ds-column-10 .ds-hero .wrapper,
.ds-column-11 .ds-hero .wrapper,
@ -2109,19 +2147,41 @@ main {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-column-gap: 24px; }
.ds-column-9 .ds-hero .cards .title,
.ds-column-10 .ds-hero .cards .title,
.ds-column-11 .ds-hero .cards .title,
.ds-column-12 .ds-hero .cards .title {
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card:hover, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card:hover, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card:hover, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card:hover {
background: none; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card:hover .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card:hover .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card:hover .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card:hover .title {
color: #45A1FF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card:active .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card:active .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card:active .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card:active .title {
color: #0A84FF; }
.ds-column-9 .ds-hero .cards .ds-card .title,
.ds-column-10 .ds-hero .cards .ds-card .title,
.ds-column-11 .ds-hero .cards .ds-card .title,
.ds-column-12 .ds-hero .cards .ds-card .title {
font-size: 14px;
line-height: 20px;
max-height: 4.28571em;
overflow: hidden; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card .title {
color: #FFF; }
.ds-hr {
border: 0;
height: 0;
border-top: 1px solid var(--newtab-border-secondary-color); }
border-top: 1px solid #D7D7DB;
height: 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hr {
border-top: 1px solid #4A4A4F; }
.ds-list {
display: grid;
@ -2156,6 +2216,8 @@ main {
display: none; }
.ds-list a {
color: #0C0C0D; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list a {
color: #F9F9FA; }
.ds-list-numbers .ds-list-item {
counter-increment: list; }
@ -2163,7 +2225,7 @@ main {
.ds-list-numbers .ds-list-item-link {
padding-inline-start: 41px; }
.ds-list-numbers .ds-list-item-link::before {
background-color: var(--newtab-link-secondary-color);
background-color: #50BCB6;
border-radius: 32px;
color: #FFF;
content: counter(list);
@ -2175,37 +2237,61 @@ main {
position: absolute;
text-align: center;
width: 32px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-numbers .ds-list-item-link::before {
background-color: #008EA4; }
.ds-list-numbers .ds-list-item-link:hover::before {
background-color: var(--newtab-link-primary-color); }
background-color: #45A1FF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-numbers .ds-list-item-link:hover::before {
background-color: #45A1FF; }
.ds-list-numbers .ds-list-item-link:active::before {
background-color: #003EAA; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-numbers .ds-list-item-link:active::before {
background-color: #0060DF; }
.ds-list-borders {
border-top: 1px solid var(--newtab-border-secondary-color);
border-top: 1px solid #D7D7DB;
grid-row-gap: 16px;
padding-top: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-borders {
border-top: 1px solid #4A4A4F; }
.ds-list-borders.ds-list-full-width .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-1 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-2 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-3 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-4 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: -1px;
padding-bottom: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-borders.ds-list-full-width .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-1 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-2 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-3 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-4 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)) {
border-bottom: 1px solid #4A4A4F; }
.ds-column-5 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)),
.ds-column-6 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)),
.ds-column-7 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)),
.ds-column-8 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: -1px;
padding-bottom: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-5 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-6 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-7 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-8 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)) {
border-bottom: 1px solid #4A4A4F; }
.ds-column-9 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)),
.ds-column-10 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)),
.ds-column-11 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)),
.ds-column-12 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: -1px;
padding-bottom: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)) {
border-bottom: 1px solid #4A4A4F; }
.ds-list-full-width .ds-list-item {
font-size: 17px;
@ -2235,7 +2321,7 @@ main {
line-height: 20px;
max-height: 2.85714em;
overflow: hidden;
color: var(--newtab-text-secondary-color);
color: rgba(249, 249, 250, 0.8);
margin: 4px 0 8px; }
.ds-list-item p {
font-size: 14px;
@ -2250,6 +2336,9 @@ main {
color: #005A71;
font-size: 13px;
text-overflow: ellipsis; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-item .ds-list-item-info, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-list-item .ds-list-item-context {
color: #A7FFFE; }
.ds-list-item .ds-list-item-title {
font-weight: 600;
margin-bottom: 4px; }
@ -2268,7 +2357,7 @@ main {
margin-inline-start: 14px;
min-height: 80px; }
.ds-list-item:hover .ds-list-item-title {
color: var(--newtab-link-primary-color); }
color: #45A1FF; }
.ds-list-item:active .ds-list-item-title {
color: #003EAA; }
@ -2293,7 +2382,7 @@ main {
.ds-navigation ul li:last-child::after {
content: none; }
.ds-navigation ul li a:hover {
border-bottom: 1px solid var(--newtab-link-primary-color); }
border-bottom: 1px solid #45A1FF; }
.ds-navigation ul li a:hover:active {
border-bottom: 1px solid #003EAA; }
.ds-navigation ul li a:active {
@ -2309,11 +2398,15 @@ main {
font-size: 36px;
font-weight: 300;
color: #0C0C0D; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-section-title .title {
color: #FFF; }
.ds-section-title .subtitle {
line-height: 24px;
font-size: 14px;
color: #737373;
margin-top: 4px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-section-title .subtitle {
color: #D7D7DB; }
.ds-top-sites .ds-header-title {
vertical-align: middle; }
@ -2394,12 +2487,80 @@ main {
.ds-column-4 .ds-top-sites .top-site-inner .title {
width: var(--rightPanelIconWidth); }
.ds-hero-item .context-menu-button,
.ds-list-item .context-menu-button,
.ds-card .context-menu-button {
background-clip: padding-box;
background-color: var(--newtab-contextmenu-button-color);
background-image: url("chrome://browser/skin/page-action.svg");
background-position: 55%;
border: 1px solid var(--newtab-border-primary-color);
border-radius: 100%;
box-shadow: 0 2px rgba(12, 12, 13, 0.1);
cursor: pointer;
fill: var(--newtab-icon-primary-color);
height: 27px;
inset-inline-end: -13.5px;
opacity: 0;
position: absolute;
top: -13.5px;
transform: scale(0.25);
transition-duration: 150ms;
transition-property: transform, opacity;
width: 27px; }
.ds-hero-item .context-menu-button:-moz-any(:active, :focus),
.ds-list-item .context-menu-button:-moz-any(:active, :focus),
.ds-card .context-menu-button:-moz-any(:active, :focus) {
opacity: 1;
transform: scale(1); }
.ds-hero-item .context-menu,
.ds-list-item .context-menu,
.ds-card .context-menu {
opacity: 0; }
.ds-hero-item.active .context-menu,
.ds-list-item.active .context-menu,
.ds-card.active .context-menu {
opacity: 1; }
.ds-hero-item.last-item .context-menu,
.ds-list-item.last-item .context-menu,
.ds-card.last-item .context-menu {
margin-inline-end: 5px;
margin-inline-start: auto;
inset-inline-end: 0;
inset-inline-start: auto; }
.ds-hero-item.last-item .context-menu,
.ds-list-item.last-item .context-menu,
.ds-card.last-item .context-menu {
opacity: 1; }
.ds-hero-item:-moz-any(:hover, :focus, .active),
.ds-list-item:-moz-any(:hover, :focus, .active),
.ds-card:-moz-any(:hover, :focus, .active) {
outline: none; }
.ds-hero-item:-moz-any(:hover, :focus, .active) .context-menu-button,
.ds-list-item:-moz-any(:hover, :focus, .active) .context-menu-button,
.ds-card:-moz-any(:hover, :focus, .active) .context-menu-button {
opacity: 1;
transform: scale(1);
transition-delay: 333ms; }
.ds-hero-item:-moz-any(:hover, :focus, .active).ds-card-grid-border,
.ds-list-item:-moz-any(:hover, :focus, .active).ds-card-grid-border,
.ds-card:-moz-any(:hover, :focus, .active).ds-card-grid-border {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
transition: box-shadow 150ms; }
.ds-card {
display: flex;
flex-direction: column;
position: relative; }
.ds-card:hover header {
color: #0060DF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card:hover header {
color: #45A1FF; }
.ds-card:active header {
color: #003EAA; }
.ds-card .img-wrapper {
@ -2413,6 +2574,11 @@ main {
box-shadow: inset 0 0 0 0.5px rgba(0, 0, 0, 0.15);
height: 0;
padding-top: 50%; }
.ds-card .ds-card-link {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%; }
.ds-card .meta {
display: flex;
flex-direction: column;
@ -2435,15 +2601,22 @@ main {
.ds-card .meta .source {
font-size: 13px;
color: #005A71; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card .meta .context, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-card .meta .source {
color: #A7FFFE; }
.ds-card header {
line-height: 24px;
font-size: 17px;
color: #0C0C0D; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card header {
color: #F9F9FA; }
.ds-card p {
font-size: 14px;
line-height: 20px;
color: #737373;
margin: 8px 0 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card p {
color: #D7D7DB; }
.ds-message {
margin: 8px 0 0; }
@ -2455,16 +2628,20 @@ main {
height: 16px;
margin: 0 6px 0 0;
-moz-context-properties: fill;
fill: var(--newtab-icon-secondary-color);
fill: #737373;
background-position: center center;
background-size: 16px;
background-repeat: no-repeat; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-message .title .glyph {
fill: #D7D7DB; }
.ds-message .title .title-text {
line-height: 20px;
font-size: 13px;
color: #737373;
font-weight: 600;
padding-right: 12px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-message .title .title-text {
color: #D7D7DB; }
.ds-message .title .link {
line-height: 20px;
font-size: 13px; }

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

@ -1842,6 +1842,8 @@ main {
font-weight: 600;
line-height: 20px;
margin: 8px 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-header {
color: #D7D7DB; }
.ds-header .icon {
fill: var(--newtab-text-secondary-color); }
@ -1885,12 +1887,19 @@ main {
.ds-card-grid .ds-card {
background: #FFF;
border-radius: 4px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card-grid .ds-card {
background: none; }
.ds-card-grid.ds-card-grid-border .ds-card {
box-shadow: var(--newtab-card-shadow); }
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1); }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card-grid.ds-card-grid-border .ds-card {
box-shadow: 0 1px 4px rgba(12, 12, 13, 0.1);
background: #38383D; }
.ds-card-grid.ds-card-grid-border .ds-card:hover {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
box-shadow: 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms;
outline: none; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card-grid.ds-card-grid-border .ds-card:hover {
box-shadow: 0 0 0 5px #4A4A4F; }
.ds-card-grid.ds-card-grid-border .ds-card .img-wrapper .img {
border-radius: 4px 4px 0 0; }
.ds-card-grid.ds-card-grid-no-border .ds-card {
@ -1965,21 +1974,34 @@ main {
margin: 0 0 12px; }
.ds-hero .img-wrapper {
margin: 0 0 12px; }
.ds-hero .ds-hero-item {
position: relative; }
.ds-hero .wrapper {
border-top: 1px solid #D7D7DB;
border-bottom: 1px solid #D7D7DB;
color: #737373;
display: block;
margin: 12px 0 16px;
padding: 16px 0;
border-top: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid var(--newtab-border-secondary-color); }
height: 100%; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper {
border-top: 1px solid #4A4A4F; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper {
border-bottom: 1px solid #4A4A4F; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper {
color: #D7D7DB; }
.ds-hero-no-border .wrapper {
border-top: 0;
border-bottom: 0;
padding: 0 0 8px; }
.ds-hero .wrapper:hover .meta header {
color: #0060DF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper:hover .meta header {
color: #45A1FF; }
.ds-hero .wrapper:active .meta header {
color: #003EAA; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper:active .meta header {
color: #45A1FF; }
.ds-hero .wrapper .img-wrapper {
width: 100%; }
.ds-hero .wrapper .img {
@ -1996,14 +2018,20 @@ main {
overflow: hidden;
color: #0C0C0D;
margin-bottom: 8px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper .meta header {
color: #FFF; }
.ds-hero .wrapper .meta .context {
color: #008EA4; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper .meta .context {
color: #A7FFFE; }
.ds-hero .wrapper .meta .source {
font-size: 13px;
color: #005A71;
margin-bottom: 0;
overflow-x: hidden;
text-overflow: ellipsis; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hero .wrapper .meta .source {
color: #A7FFFE; }
.ds-column-5 .ds-hero .wrapper,
.ds-column-6 .ds-hero .wrapper,
.ds-column-7 .ds-hero .wrapper,
@ -2049,14 +2077,24 @@ main {
.ds-column-10 .ds-hero.ds-hero-border,
.ds-column-11 .ds-hero.ds-hero-border,
.ds-column-12 .ds-hero.ds-hero-border {
border-top: 1px solid var(--newtab-border-secondary-color);
border-top: 1px solid #D7D7DB;
padding: 20px 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero.ds-hero-border, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero.ds-hero-border, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero.ds-hero-border, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero.ds-hero-border {
border-top: 1px solid #4A4A4F; }
.ds-column-9 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2),
.ds-column-10 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2),
.ds-column-11 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2),
.ds-column-12 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: 20px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero.ds-hero-border .ds-card:nth-child(-n+2) {
border-bottom: 1px solid #4A4A4F; }
.ds-column-9 .ds-hero .wrapper,
.ds-column-10 .ds-hero .wrapper,
.ds-column-11 .ds-hero .wrapper,
@ -2106,19 +2144,41 @@ main {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-column-gap: 24px; }
.ds-column-9 .ds-hero .cards .title,
.ds-column-10 .ds-hero .cards .title,
.ds-column-11 .ds-hero .cards .title,
.ds-column-12 .ds-hero .cards .title {
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card:hover, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card:hover, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card:hover, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card:hover {
background: none; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card:hover .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card:hover .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card:hover .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card:hover .title {
color: #45A1FF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card:active .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card:active .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card:active .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card:active .title {
color: #0A84FF; }
.ds-column-9 .ds-hero .cards .ds-card .title,
.ds-column-10 .ds-hero .cards .ds-card .title,
.ds-column-11 .ds-hero .cards .ds-card .title,
.ds-column-12 .ds-hero .cards .ds-card .title {
font-size: 14px;
line-height: 20px;
max-height: 4.28571em;
overflow: hidden; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-hero .cards .ds-card .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-hero .cards .ds-card .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-hero .cards .ds-card .title, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-hero .cards .ds-card .title {
color: #FFF; }
.ds-hr {
border: 0;
height: 0;
border-top: 1px solid var(--newtab-border-secondary-color); }
border-top: 1px solid #D7D7DB;
height: 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-hr {
border-top: 1px solid #4A4A4F; }
.ds-list {
display: grid;
@ -2153,6 +2213,8 @@ main {
display: none; }
.ds-list a {
color: #0C0C0D; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list a {
color: #F9F9FA; }
.ds-list-numbers .ds-list-item {
counter-increment: list; }
@ -2160,7 +2222,7 @@ main {
.ds-list-numbers .ds-list-item-link {
padding-inline-start: 41px; }
.ds-list-numbers .ds-list-item-link::before {
background-color: var(--newtab-link-secondary-color);
background-color: #50BCB6;
border-radius: 32px;
color: #FFF;
content: counter(list);
@ -2172,37 +2234,61 @@ main {
position: absolute;
text-align: center;
width: 32px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-numbers .ds-list-item-link::before {
background-color: #008EA4; }
.ds-list-numbers .ds-list-item-link:hover::before {
background-color: var(--newtab-link-primary-color); }
background-color: #45A1FF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-numbers .ds-list-item-link:hover::before {
background-color: #45A1FF; }
.ds-list-numbers .ds-list-item-link:active::before {
background-color: #003EAA; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-numbers .ds-list-item-link:active::before {
background-color: #0060DF; }
.ds-list-borders {
border-top: 1px solid var(--newtab-border-secondary-color);
border-top: 1px solid #D7D7DB;
grid-row-gap: 16px;
padding-top: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-borders {
border-top: 1px solid #4A4A4F; }
.ds-list-borders.ds-list-full-width .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-1 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-2 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-3 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)),
.ds-column-4 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: -1px;
padding-bottom: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-borders.ds-list-full-width .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-1 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-2 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-3 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-4 .ds-list-borders .ds-list-item:not(:nth-last-child(-n+1)) {
border-bottom: 1px solid #4A4A4F; }
.ds-column-5 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)),
.ds-column-6 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)),
.ds-column-7 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)),
.ds-column-8 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: -1px;
padding-bottom: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-5 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-6 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-7 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-8 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+2)) {
border-bottom: 1px solid #4A4A4F; }
.ds-column-9 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)),
.ds-column-10 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)),
.ds-column-11 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)),
.ds-column-12 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)) {
border-bottom: 1px solid var(--newtab-border-secondary-color);
border-bottom: 1px solid #D7D7DB;
margin-bottom: -1px;
padding-bottom: 16px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-column-9 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-10 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-11 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)), [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-column-12 .ds-list-borders:not(.ds-list-full-width) .ds-list-item:not(:nth-last-child(-n+3)) {
border-bottom: 1px solid #4A4A4F; }
.ds-list-full-width .ds-list-item {
font-size: 17px;
@ -2232,7 +2318,7 @@ main {
line-height: 20px;
max-height: 2.85714em;
overflow: hidden;
color: var(--newtab-text-secondary-color);
color: rgba(249, 249, 250, 0.8);
margin: 4px 0 8px; }
.ds-list-item p {
font-size: 14px;
@ -2247,6 +2333,9 @@ main {
color: #005A71;
font-size: 13px;
text-overflow: ellipsis; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-list-item .ds-list-item-info, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-list-item .ds-list-item-context {
color: #A7FFFE; }
.ds-list-item .ds-list-item-title {
font-weight: 600;
margin-bottom: 4px; }
@ -2265,7 +2354,7 @@ main {
margin-inline-start: 14px;
min-height: 80px; }
.ds-list-item:hover .ds-list-item-title {
color: var(--newtab-link-primary-color); }
color: #45A1FF; }
.ds-list-item:active .ds-list-item-title {
color: #003EAA; }
@ -2290,7 +2379,7 @@ main {
.ds-navigation ul li:last-child::after {
content: none; }
.ds-navigation ul li a:hover {
border-bottom: 1px solid var(--newtab-link-primary-color); }
border-bottom: 1px solid #45A1FF; }
.ds-navigation ul li a:hover:active {
border-bottom: 1px solid #003EAA; }
.ds-navigation ul li a:active {
@ -2306,11 +2395,15 @@ main {
font-size: 36px;
font-weight: 300;
color: #0C0C0D; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-section-title .title {
color: #FFF; }
.ds-section-title .subtitle {
line-height: 24px;
font-size: 14px;
color: #737373;
margin-top: 4px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-section-title .subtitle {
color: #D7D7DB; }
.ds-top-sites .ds-header-title {
vertical-align: middle; }
@ -2391,12 +2484,80 @@ main {
.ds-column-4 .ds-top-sites .top-site-inner .title {
width: var(--rightPanelIconWidth); }
.ds-hero-item .context-menu-button,
.ds-list-item .context-menu-button,
.ds-card .context-menu-button {
background-clip: padding-box;
background-color: var(--newtab-contextmenu-button-color);
background-image: url("chrome://browser/skin/page-action.svg");
background-position: 55%;
border: 1px solid var(--newtab-border-primary-color);
border-radius: 100%;
box-shadow: 0 2px rgba(12, 12, 13, 0.1);
cursor: pointer;
fill: var(--newtab-icon-primary-color);
height: 27px;
inset-inline-end: -13.5px;
opacity: 0;
position: absolute;
top: -13.5px;
transform: scale(0.25);
transition-duration: 150ms;
transition-property: transform, opacity;
width: 27px; }
.ds-hero-item .context-menu-button:-moz-any(:active, :focus),
.ds-list-item .context-menu-button:-moz-any(:active, :focus),
.ds-card .context-menu-button:-moz-any(:active, :focus) {
opacity: 1;
transform: scale(1); }
.ds-hero-item .context-menu,
.ds-list-item .context-menu,
.ds-card .context-menu {
opacity: 0; }
.ds-hero-item.active .context-menu,
.ds-list-item.active .context-menu,
.ds-card.active .context-menu {
opacity: 1; }
.ds-hero-item.last-item .context-menu,
.ds-list-item.last-item .context-menu,
.ds-card.last-item .context-menu {
margin-inline-end: 5px;
margin-inline-start: auto;
inset-inline-end: 0;
inset-inline-start: auto; }
.ds-hero-item.last-item .context-menu,
.ds-list-item.last-item .context-menu,
.ds-card.last-item .context-menu {
opacity: 1; }
.ds-hero-item:-moz-any(:hover, :focus, .active),
.ds-list-item:-moz-any(:hover, :focus, .active),
.ds-card:-moz-any(:hover, :focus, .active) {
outline: none; }
.ds-hero-item:-moz-any(:hover, :focus, .active) .context-menu-button,
.ds-list-item:-moz-any(:hover, :focus, .active) .context-menu-button,
.ds-card:-moz-any(:hover, :focus, .active) .context-menu-button {
opacity: 1;
transform: scale(1);
transition-delay: 333ms; }
.ds-hero-item:-moz-any(:hover, :focus, .active).ds-card-grid-border,
.ds-list-item:-moz-any(:hover, :focus, .active).ds-card-grid-border,
.ds-card:-moz-any(:hover, :focus, .active).ds-card-grid-border {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
transition: box-shadow 150ms; }
.ds-card {
display: flex;
flex-direction: column;
position: relative; }
.ds-card:hover header {
color: #0060DF; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card:hover header {
color: #45A1FF; }
.ds-card:active header {
color: #003EAA; }
.ds-card .img-wrapper {
@ -2410,6 +2571,11 @@ main {
box-shadow: inset 0 0 0 0.5px rgba(0, 0, 0, 0.15);
height: 0;
padding-top: 50%; }
.ds-card .ds-card-link {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%; }
.ds-card .meta {
display: flex;
flex-direction: column;
@ -2432,15 +2598,22 @@ main {
.ds-card .meta .source {
font-size: 13px;
color: #005A71; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card .meta .context, [lwt-newtab-brighttext]:not(.force-light-theme)
.ds-card .meta .source {
color: #A7FFFE; }
.ds-card header {
line-height: 24px;
font-size: 17px;
color: #0C0C0D; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card header {
color: #F9F9FA; }
.ds-card p {
font-size: 14px;
line-height: 20px;
color: #737373;
margin: 8px 0 0; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-card p {
color: #D7D7DB; }
.ds-message {
margin: 8px 0 0; }
@ -2452,16 +2625,20 @@ main {
height: 16px;
margin: 0 6px 0 0;
-moz-context-properties: fill;
fill: var(--newtab-icon-secondary-color);
fill: #737373;
background-position: center center;
background-size: 16px;
background-repeat: no-repeat; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-message .title .glyph {
fill: #D7D7DB; }
.ds-message .title .title-text {
line-height: 20px;
font-size: 13px;
color: #737373;
font-weight: 600;
padding-right: 12px; }
[lwt-newtab-brighttext]:not(.force-light-theme) .ds-message .title .title-text {
color: #D7D7DB; }
.ds-message .title .link {
line-height: 20px;
font-size: 13px; }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -267,5 +267,7 @@ This encoding mapping was defined in `system-addon/lib/TelemetryFeed.jsm`
| `showHighlights` | 8 |
| `showSnippets` | 16 |
| `showSponsored` | 32 |
| `showCFRAddons` | 64 |
| `showCFRFeatures` | 128 |
Each item above could be combined with other items through bitwise OR operation

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

@ -949,7 +949,7 @@ This reports the user's interaction with Activity Stream Router.
"source": "CFR",
// message_id could be the ID of the recommendation, such as "wikipedia_addon"
"message_id": "wikipedia_addon",
"event": "[INSTALL | BLOCK | DISMISS | RATIONALE | LEARN_MORE | CLICK_DOORHANGER | MANAGE]"
"event": "[INSTALL | PIN | BLOCK | DISMISS | RATIONALE | LEARN_MORE | CLICK_DOORHANGER | MANAGE]"
}
```
@ -965,7 +965,7 @@ This reports the user's interaction with Activity Stream Router.
// message_id should be a bucket ID in the release channel, we may not use the
// individual ID, such as addon ID, per legal's request
"message_id": "bucket_id",
"event": "[INSTALL | BLOCK | DISMISS | RATIONALE | LEARN_MORE | CLICK_DOORHANGER | MANAGE]"
"event": "[INSTALL | PIN | BLOCK | DISMISS | RATIONALE | LEARN_MORE | CLICK_DOORHANGER | MANAGE]"
}
```

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

@ -419,7 +419,7 @@ class _ASRouter {
for (const provider of this.state.providers) {
if (needsUpdate.includes(provider)) {
let {messages, lastUpdated} = await MessageLoaderUtils.loadMessagesForProvider(provider, this._storage);
messages = messages.filter(({category}) => !category || ASRouterPreferences.getUserPreference(category));
messages = messages.filter(({content}) => !content || !content.category || ASRouterPreferences.getUserPreference(content.category));
newState.providers.push({...provider, lastUpdated});
newState.messages = [...newState.messages, ...messages];
} else {

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

@ -37,14 +37,21 @@ const REDDIT_ENHANCEMENT_PARAMS = {
sumo_path: "extensionrecommendations",
min_frecency: 10000,
};
const PINNED_TABS_TARGET_SITES = ["trello.com", "www.trello.com", "wunderlist.com", "www.wunderlist.com", "docs.google.com", "www.docs.google.com", "calendar.google.com", "www.calendar.google.com", "simplenote.com", "www.simplenote.com", "airtable.com", "www.airtable.com", "todoist.com", "www.todoist.com", "slack.com", "www.slack.com", "irccloud.com", "www.irccloud.com", "products.office.com", "www.products.office.com", "messenger.com", "www.messenger.com", "discordapp.com", "www.discordapp.com", "web.wechat.com", "www.web.wechat.com", "web.whatsapp.com", "www.web.whatsapp.com", "gmail.com", "www.gmail.com", "mail.yahoo.com", "www.mail.yahoo.com", "outlook.com", "www.outlook.com", "polymail.io", "www.polymail.io", "icloud.com", "www.icloud.com", "mail.aol.com", "www.mail.aol.com", "lightroom.adobe.com", "www.lightroom.adobe.com", "facebook.com", "www.facebook.com", "twitter.com", "www.twitter.com", "instagram.com", "www.instagram.com", "pinterest.com", "www.pinterest.com", "reddit.com", "www.reddit.com", "coursera.org", "www.coursera.org", "edx.org", "www.edx.org", "udemy.com", "www.udemy.com", "skillshare.com", "www.skillshare.com", "pluralsight.com", "www.pluralsight.com", "udacity.com", "www.udacity.com", "tumblr.com", "www.tumblr.com", "quora.com", "www.quora.com", "deviantart.com", "www.deviantart.com", "github.com", "www.github.com", "kaggle.com", "www.kaggle.com", "dropbox.com", "www.dropbox.com", "drive.google.com", "www.drive.google.com", "box.com", "www.box.com", "netflix.com", "www.netflix.com", "primevideo.com", "www.primevideo.com", "hulu.com", "www.hulu.com", "crave.ca", "www.crave.ca", "twitch.tv", "www.twitch.tv", "youtube.com", "www.youtube.com", "craigslist.org", "www.craigslist.org", "kijiji.ca", "www.kijiji.ca"];
const PINNED_TABS_TARGET_SITES = [
"docs.google.com", "www.docs.google.com", "calendar.google.com",
"messenger.com", "www.messenger.com", "web.whatsapp.com", "mail.google.com",
"outlook.live.com", "facebook.com", "www.facebook.com", "twitter.com", "www.twitter.com",
"reddit.com", "www.reddit.com", "github.com", "www.github.com", "youtube.com", "www.youtube.com",
"feedly.com", "www.feedly.com", "drive.google.com", "amazon.com", "www.amazon.com",
"messages.android.com",
];
const CFR_MESSAGES = [
{
id: "FACEBOOK_CONTAINER_3",
template: "cfr_doorhanger",
category: "cfrAddons",
content: {
category: "cfrAddons",
bucket_id: "CFR_M1",
notification_text: {string_id: "cfr-doorhanger-extension-notification"},
heading_text: {string_id: "cfr-doorhanger-extension-heading"},
@ -95,8 +102,8 @@ const CFR_MESSAGES = [
{
id: "GOOGLE_TRANSLATE_3",
template: "cfr_doorhanger",
category: "cfrAddons",
content: {
category: "cfrAddons",
bucket_id: "CFR_M1",
notification_text: {string_id: "cfr-doorhanger-extension-notification"},
heading_text: {string_id: "cfr-doorhanger-extension-heading"},
@ -147,8 +154,8 @@ const CFR_MESSAGES = [
{
id: "YOUTUBE_ENHANCE_3",
template: "cfr_doorhanger",
category: "cfrAddons",
content: {
category: "cfrAddons",
bucket_id: "CFR_M1",
notification_text: {string_id: "cfr-doorhanger-extension-notification"},
heading_text: {string_id: "cfr-doorhanger-extension-heading"},
@ -199,9 +206,9 @@ const CFR_MESSAGES = [
{
id: "WIKIPEDIA_CONTEXT_MENU_SEARCH_3",
template: "cfr_doorhanger",
category: "cfrAddons",
exclude: true,
content: {
category: "cfrAddons",
bucket_id: "CFR_M1",
notification_text: {string_id: "cfr-doorhanger-extension-notification"},
heading_text: {string_id: "cfr-doorhanger-extension-heading"},
@ -252,9 +259,9 @@ const CFR_MESSAGES = [
{
id: "REDDIT_ENHANCEMENT_3",
template: "cfr_doorhanger",
category: "cfrAddons",
exclude: true,
content: {
category: "cfrAddons",
bucket_id: "CFR_M1",
notification_text: {string_id: "cfr-doorhanger-extension-notification"},
heading_text: {string_id: "cfr-doorhanger-extension-heading"},
@ -305,9 +312,8 @@ const CFR_MESSAGES = [
{
id: "PIN_TAB",
template: "cfr_doorhanger",
category: "cfrFeatures",
exclude: true,
content: {
category: "cfrFeatures",
bucket_id: "CFR_PIN_TAB",
notification_text: {string_id: "cfr-doorhanger-extension-notification"},
heading_text: {string_id: "cfr-doorhanger-pintab-heading"},
@ -315,7 +321,14 @@ const CFR_MESSAGES = [
label: {string_id: "cfr-doorhanger-extension-sumo-link"},
sumo_path: REDDIT_ENHANCEMENT_PARAMS.sumo_path,
},
text: "Get easy access to your most-used sites. Keep sites open in a tab (even when you restart).",
text: {string_id: "cfr-doorhanger-pintab-description"},
descriptionDetails: {
steps: [
{"string_id": "cfr-doorhanger-pintab-step1"},
{"string_id": "cfr-doorhanger-pintab-step2"},
{"string_id": "cfr-doorhanger-pintab-step3"},
],
},
buttons: {
primary: {
label: {string_id: "cfr-doorhanger-pintab-ok-button"},
@ -337,7 +350,8 @@ const CFR_MESSAGES = [
}],
},
},
targeting: `!hasPinnedTabs && recentVisits[.timestamp > (currentDate|date - 3600 * 1000 * 1)]|length >= 1`,
targeting: `localeLanguageCode == "en" && !hasPinnedTabs && recentVisits[.timestamp > (currentDate|date - 3600 * 1000 * 1)]|length >= 3`,
frequency: {lifetime: 3},
trigger: {id: "frequentVisits", params: PINNED_TABS_TARGET_SITES},
},
];

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

@ -4,7 +4,7 @@
"use strict";
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const {Localization} = ChromeUtils.import("resource://gre/modules/Localization.jsm");
const {DOMLocalization} = ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm");
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]);
@ -12,10 +12,16 @@ ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
const POPUP_NOTIFICATION_ID = "contextual-feature-recommendation";
const PAUSE_BUTTON_ID = "cfr-notification-footer-pause-button";
const SUMO_BASE_URL = Services.urlFormatter.formatURLPref("app.support.baseURL");
const ADDONS_API_URL = "https://services.addons.mozilla.org/api/v3/addons/addon";
const ANIMATIONS_ENABLED_PREF = "toolkit.cosmeticAnimations.enabled";
const DELAY_BEFORE_EXPAND_MS = 1000;
const CATEGORY_ICONS = {
"cfrAddons": "webextensions-icon",
"cfrFeatures": "recommendations-icon",
};
/**
* A WeakMap from browsers to {host, recommendation} pairs. Recommendations are
@ -52,7 +58,7 @@ class PageAction {
this._showPopupOnClick = this._showPopupOnClick.bind(this);
this.dispatchUserAction = this.dispatchUserAction.bind(this);
this._l10n = new Localization([
this._l10n = new DOMLocalization([
"browser/newtab/asrouter.ftl",
]);
@ -64,6 +70,7 @@ class PageAction {
this.container.hidden = false;
this.label.value = await this.getStrings(recommendation.content.notification_text);
this.button.setAttribute("data-cfr-icon", CATEGORY_ICONS[recommendation.content.category]);
// Wait for layout to flush to avoid a synchronous reflow then calculate the
// label width. We can safely get the width even though the recommendation is
@ -131,6 +138,13 @@ class PageAction {
this.urlbar.setAttribute("cfr-recommendation-state", "collapsed");
}
}
// TODO: FIXME: find a nicer way of cleaning this up. Maybe listening to "popuphidden"?
// Remove click listener on pause button;
if (this.onPauseClick) {
this.window.document.getElementById(PAUSE_BUTTON_ID).removeEventListener("click", this.onPauseClick);
delete this.onPauseClick;
}
}
_clearScheduledStateChanges() {
@ -221,33 +235,18 @@ class PageAction {
return subAttribute ? mainString.attributes[subAttribute] : mainString;
}
async _renderPopup(message, browser) { // eslint-disable-line max-statements
const {id, content} = message;
const headerLabel = this.window.document.getElementById("cfr-notification-header-label");
const headerLink = this.window.document.getElementById("cfr-notification-header-link");
const headerImage = this.window.document.getElementById("cfr-notification-header-image");
async _setAddonAuthorAndRating(document, content) {
const author = this.window.document.getElementById("cfr-notification-author");
const footerText = this.window.document.getElementById("cfr-notification-footer-text");
const footerFilledStars = this.window.document.getElementById("cfr-notification-footer-filled-stars");
const footerEmptyStars = this.window.document.getElementById("cfr-notification-footer-empty-stars");
const footerUsers = this.window.document.getElementById("cfr-notification-footer-users");
const footerSpacer = this.window.document.getElementById("cfr-notification-footer-spacer");
const footerLink = this.window.document.getElementById("cfr-notification-footer-learn-more-link");
headerLabel.value = await this.getStrings(content.heading_text);
headerLink.setAttribute("href", SUMO_BASE_URL + content.info_icon.sumo_path);
headerLink.setAttribute(this.window.RTL_UI ? "left" : "right", 0);
headerImage.setAttribute("tooltiptext", await this.getStrings(content.info_icon.label, "tooltiptext"));
headerLink.onclick = () => this._sendTelemetry({message_id: id, bucket_id: content.bucket_id, event: "RATIONALE"});
author.textContent = await this.getStrings({
string_id: "cfr-doorhanger-extension-author",
args: {name: content.addon.author},
});
footerText.textContent = await this.getStrings(content.text);
const {rating} = content.addon;
if (rating) {
const MAX_RATING = 5;
@ -288,13 +287,132 @@ class PageAction {
} else {
footerSpacer.setAttribute("hidden", true);
}
}
footerLink.value = await this.getStrings({string_id: "cfr-doorhanger-extension-learn-more-link"});
footerLink.setAttribute("href", content.addon.amo_url);
footerLink.onclick = () => this._sendTelemetry({message_id: id, bucket_id: content.bucket_id, event: "LEARN_MORE"});
_createElementAndAppend({type, id}, parent) {
let element = this.window.document.createElement(type);
if (id) {
element.setAttribute("id", id);
}
parent.appendChild(element);
return element;
}
async _renderPinTabAnimation() {
const ANIMATION_CONTAINER_ID = "cfr-notification-footer-pintab-animation-container";
const footer = this.window.document.getElementById("cfr-notification-footer");
let animationContainer = this.window.document.getElementById(ANIMATION_CONTAINER_ID);
if (!animationContainer) {
animationContainer = this._createElementAndAppend({type: "vbox", id: ANIMATION_CONTAINER_ID}, footer);
// spacer
this._createElementAndAppend("vbox", animationContainer).setAttribute("flex", 1);
let controlsContainer = this._createElementAndAppend(
{type: "hbox", id: "cfr-notification-footer-animation-controls"}, animationContainer);
// spacer
this._createElementAndAppend({type: "vbox"}, controlsContainer).setAttribute("flex", 1);
let pauseButton = this._createElementAndAppend({type: "hbox", id: PAUSE_BUTTON_ID}, controlsContainer);
let pauseLabel = this._createElementAndAppend(
{type: "label", id: "cfr-notification-footer-pause-label"}, pauseButton);
pauseLabel.textContent = await this.getStrings({"string_id": "cfr-doorhanger-pintab-animation-pause"});
// pause icon
this._createElementAndAppend({type: "image", id: "cfr-notification-footer-pause-icon"}, pauseButton);
}
animationContainer.toggleAttribute("animate", Services.prefs.getBoolPref(ANIMATIONS_ENABLED_PREF, true));
animationContainer.removeAttribute("paused");
if (!this.onPauseClick) {
let pauseButton = this.window.document.getElementById(PAUSE_BUTTON_ID);
this.onPauseClick = () => { animationContainer.setAttribute("paused", true); };
pauseButton.addEventListener("click", this.onPauseClick);
}
}
async _renderPopup(message, browser) {
const {id, content} = message;
const headerLabel = this.window.document.getElementById("cfr-notification-header-label");
const headerLink = this.window.document.getElementById("cfr-notification-header-link");
const headerImage = this.window.document.getElementById("cfr-notification-header-image");
const footerText = this.window.document.getElementById("cfr-notification-footer-text");
const footerLink = this.window.document.getElementById("cfr-notification-footer-learn-more-link");
const {primary, secondary} = content.buttons;
let primaryActionCallback;
let options = {};
let panelTitle;
// Use the message category as a CSS selector to hide different parts of the
// notification template markup
this.window.document.getElementById("contextual-feature-recommendation-notification")
.setAttribute("data-notification-category", message.content.category);
headerLabel.value = await this.getStrings(content.heading_text);
headerLink.setAttribute("href", SUMO_BASE_URL + content.info_icon.sumo_path);
headerLink.setAttribute(this.window.RTL_UI ? "left" : "right", 0);
headerImage.setAttribute("tooltiptext", await this.getStrings(content.info_icon.label, "tooltiptext"));
headerLink.onclick = () => this._sendTelemetry({message_id: id, bucket_id: content.bucket_id, event: "RATIONALE"});
footerText.textContent = await this.getStrings(content.text);
if (content.addon) {
await this._setAddonAuthorAndRating(this.window.document, content);
panelTitle = await this.getStrings(content.addon.title);
options = {popupIconURL: content.addon.icon};
footerLink.value = await this.getStrings({string_id: "cfr-doorhanger-extension-learn-more-link"});
footerLink.setAttribute("href", content.addon.amo_url);
footerLink.onclick = () => this._sendTelemetry({message_id: id, bucket_id: content.bucket_id, event: "LEARN_MORE"});
primaryActionCallback = async () => {
primary.action.data.url = await CFRPageActions._fetchLatestAddonVersion(content.addon.id); // eslint-disable-line no-use-before-define
this._blockMessage(id);
this.dispatchUserAction(primary.action);
this.hideAddressBarNotifier();
this._sendTelemetry({message_id: id, bucket_id: content.bucket_id, event: "INSTALL"});
RecommendationMap.delete(browser);
};
} else {
const stepsContainerId = "cfr-notification-feature-steps";
let stepsContainer = this.window.document.getElementById(stepsContainerId);
primaryActionCallback = () => {
this._blockMessage(id);
this.dispatchUserAction(primary.action);
this.hideAddressBarNotifier();
this._sendTelemetry({message_id: id, bucket_id: content.bucket_id, event: "PIN"});
RecommendationMap.delete(browser);
};
panelTitle = await this.getStrings(content.heading_text);
if (stepsContainer) { // If it exists we need to empty it
stepsContainer.remove();
stepsContainer = stepsContainer.cloneNode(false);
} else {
stepsContainer = this.window.document.createElement("vbox");
stepsContainer.setAttribute("id", stepsContainerId);
}
footerText.parentNode.appendChild(stepsContainer);
for (let step of content.descriptionDetails.steps) {
const li = this.window.document.createElement("li");
this._l10n.setAttributes(li, step.string_id);
stepsContainer.appendChild(li);
}
await this._l10n.translateElements([...stepsContainer.children]);
await this._renderPinTabAnimation();
}
const primaryBtnStrings = await this.getStrings(primary.label);
const mainAction = {
label: primaryBtnStrings,
accessKey: primaryBtnStrings.attributes.accesskey,
callback: primaryActionCallback,
};
// For each secondary action, get the strings and attributes
const secondaryBtnStrings = [];
@ -302,20 +420,6 @@ class PageAction {
let label = await this.getStrings(button.label);
secondaryBtnStrings.push({label, attributes: label.attributes});
}
const mainAction = {
label: primaryBtnStrings,
accessKey: primaryBtnStrings.attributes.accesskey,
callback: async () => {
primary.action.data.url = await CFRPageActions._fetchLatestAddonVersion(content.addon.id); // eslint-disable-line no-use-before-define
this._blockMessage(id);
this.dispatchUserAction(primary.action);
this.hideAddressBarNotifier();
this._sendTelemetry({message_id: id, bucket_id: content.bucket_id, event: "INSTALL"});
RecommendationMap.delete(browser);
},
};
const secondaryActions = [{
label: secondaryBtnStrings[0].label,
accessKey: secondaryBtnStrings[0].attributes.accesskey,
@ -341,21 +445,19 @@ class PageAction {
},
}];
const options = {
popupIconURL: content.addon.icon,
hideClose: true,
eventCallback: this._popupStateChange,
};
// Actually show the notification
this.currentNotification = this.window.PopupNotifications.show(
browser,
POPUP_NOTIFICATION_ID,
await this.getStrings(content.addon.title),
panelTitle,
"cfr",
mainAction,
secondaryActions,
options
{
...options,
hideClose: true,
eventCallback: this._popupStateChange,
}
);
}

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

@ -1,4 +1,3 @@
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
@ -42,7 +41,7 @@ this.DownloadsManager = class DownloadsManager {
init(store) {
this._store = store;
this._downloadData = DownloadsCommon.getData(null /* null for non-private downloads */,
this._downloadData = DownloadsCommon.getData(null /* null for non-private downloads */,
true, false, true);
this._downloadData.addView(this);
}

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

@ -49,6 +49,8 @@ const USER_PREFS_ENCODING = {
"feeds.section.highlights": 1 << 3,
"feeds.snippets": 1 << 4,
"showSponsored": 1 << 5,
"asrouter.userprefs.cfr.addons": 1 << 6,
"asrouter.userprefs.cfr.features": 1 << 7,
};
const PREF_IMPRESSION_ID = "impressionId";

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

@ -91,6 +91,9 @@ section_disclaimer_topstories_buttontext=Oke, paham
# what is shown for the homepage, new windows, and new tabs.
prefs_home_header=Konten Beranda Firefox
prefs_home_description=Pilih konten yang ingin Anda tampilkan dalam Beranda Firefox.
prefs_content_discovery_header=Beranda Firefox
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
# plural forms used in a drop down of multiple row options (1 row, 2 rows).
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
@ -144,7 +147,6 @@ pocket_read_more=Topik Populer:
# end of the list of popular topic links.
pocket_read_even_more=Lihat Cerita Lainnya
pocket_more_reccommendations=Rekomendasi Lainnya
pocket_learn_more=Pelajari Lebih Lanjut
pocket_how_it_works=Panduan
pocket_cta_button=Dapatkan Pocket
pocket_cta_text=Simpan cerita yang anda sukai di Pocket, dan dapatkan bacaan menarik untuk Anda.

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

@ -93,6 +93,8 @@ prefs_home_header=Innhold Firefox-startside
prefs_home_description=Velg hvilket innhold som du vil ha på din Firefox-startside.
prefs_content_discovery_header=Firefox startside
prefs_content_discovery_description=Innholdsoppdagelse på Firefox startside lar deg oppdage relevante artikler av høy kvalitet fra nettet.
prefs_content_discovery_button=Slå av innholdsoppdagelse
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
# plural forms used in a drop down of multiple row options (1 row, 2 rows).

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

@ -35,7 +35,7 @@ menu_action_open_private_window=Opne i eit nytt privat vindauge
menu_action_dismiss=Avvis
menu_action_delete=Slett frå historikk
menu_action_pin=Fest
menu_action_unpin=L:ys
menu_action_unpin=Løys
confirm_history_delete_p1=Er du sikker på at du vil slette alle førekomstar av denne sida frå historikken din?
# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
@ -93,6 +93,7 @@ prefs_home_header=Innhald Firefox-startside
prefs_home_description=Vel kva for innhald du vil ha på Firefox-startsida di.
prefs_content_discovery_header=Firefox startside
prefs_content_discovery_description=Innhaldsoppdaging på Firefox startside lèt deg oppdage relevante artiklar av høg kvalitet frå nettet.
prefs_content_discovery_button=Slå av innhaldsoppdaging
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of

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

@ -40,7 +40,7 @@ window.gActivityStreamStrings = {
"section_disclaimer_topstories_buttontext": "Oke, paham",
"prefs_home_header": "Konten Beranda Firefox",
"prefs_home_description": "Pilih konten yang ingin Anda tampilkan dalam Beranda Firefox.",
"prefs_content_discovery_header": "Firefox Home",
"prefs_content_discovery_header": "Beranda Firefox",
"prefs_content_discovery_description": "Content Discovery in Firefox Home allows you to discover high-quality, relevant articles from across the web.",
"prefs_content_discovery_button": "Turn Off Content Discovery",
"prefs_section_rows_option": "{num} baris",
@ -110,6 +110,5 @@ window.gActivityStreamStrings = {
"firstrun_privacy_notice": "Pernyataan Privasi",
"firstrun_continue_to_login": "Lanjutkan",
"firstrun_skip_login": "Lewati langkah ini",
"context_menu_title": "Buka menu",
"pocket_learn_more": "Pelajari Lebih Lanjut"
"context_menu_title": "Buka menu"
};

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

@ -41,8 +41,8 @@ window.gActivityStreamStrings = {
"prefs_home_header": "Innhold Firefox-startside",
"prefs_home_description": "Velg hvilket innhold som du vil ha på din Firefox-startside.",
"prefs_content_discovery_header": "Firefox startside",
"prefs_content_discovery_description": "Content Discovery in Firefox Home allows you to discover high-quality, relevant articles from across the web.",
"prefs_content_discovery_button": "Turn Off Content Discovery",
"prefs_content_discovery_description": "Innholdsoppdagelse på Firefox startside lar deg oppdage relevante artikler av høy kvalitet fra nettet.",
"prefs_content_discovery_button": "Slå av innholdsoppdagelse",
"prefs_section_rows_option": "{num} rekke;{num} rekker",
"prefs_search_header": "Nettsøk",
"prefs_topsites_description": "Mest besøkte nettsteder",

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

@ -18,7 +18,7 @@ window.gActivityStreamStrings = {
"menu_action_dismiss": "Avvis",
"menu_action_delete": "Slett frå historikk",
"menu_action_pin": "Fest",
"menu_action_unpin": "L:ys",
"menu_action_unpin": "Løys",
"confirm_history_delete_p1": "Er du sikker på at du vil slette alle førekomstar av denne sida frå historikken din?",
"confirm_history_delete_notice_p2": "Denne handlinga kan ikkje angrast.",
"menu_action_save_to_pocket": "Lagre til Pocket",
@ -41,7 +41,7 @@ window.gActivityStreamStrings = {
"prefs_home_header": "Innhald Firefox-startside",
"prefs_home_description": "Vel kva for innhald du vil ha på Firefox-startsida di.",
"prefs_content_discovery_header": "Firefox startside",
"prefs_content_discovery_description": "Content Discovery in Firefox Home allows you to discover high-quality, relevant articles from across the web.",
"prefs_content_discovery_description": "Innhaldsoppdaging på Firefox startside lèt deg oppdage relevante artiklar av høg kvalitet frå nettet.",
"prefs_content_discovery_button": "Slå av innhaldsoppdaging",
"prefs_section_rows_option": "{num} rekkje;{num} rekkjer",
"prefs_search_header": "Nettsøk",

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

@ -967,12 +967,14 @@ describe("ASRouter", () => {
describe("#onMessage: PIN_CURRENT_TAB", () => {
it("should call pin tab with the selectedTab", async () => {
const msg = fakeExecuteUserAction({type: "PIN_CURRENT_TAB"});
const {gBrowser} = msg.target.browser.ownerGlobal;
const {gBrowser, ConfirmationHint} = msg.target.browser.ownerGlobal;
await Router.onMessage(msg);
assert.calledOnce(gBrowser.pinTab);
assert.calledWithExactly(gBrowser.pinTab, gBrowser.selectedTab);
assert.calledOnce(ConfirmationHint.show);
assert.calledWithExactly(ConfirmationHint.show, gBrowser.selectedTab, "pinTab", {showDescription: true});
});
});

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

@ -11,8 +11,8 @@ const REGULAR_IDS = [
];
describe("CFRMessageProvider", () => {
it("should have a total of 3 messages", () => {
assert.lengthOf(messages, 3);
it("should have a total of 4 messages", () => {
assert.lengthOf(messages, 4);
});
it("should have one message each for the three regular addons", () => {
for (const id of REGULAR_IDS) {
@ -32,4 +32,9 @@ describe("CFRMessageProvider", () => {
}
}
});
it("should restrict all messages to `en` locale for now", () => {
for (const message of messages) {
assert.include(message.targeting, `localeLanguageCode == "en"`);
}
});
});

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

@ -22,12 +22,18 @@ describe("CFRPageActions", () => {
"cfr-notification-header-link",
"cfr-notification-header-image",
"cfr-notification-author",
"cfr-notification-footer",
"cfr-notification-footer-text",
"cfr-notification-footer-filled-stars",
"cfr-notification-footer-empty-stars",
"cfr-notification-footer-users",
"cfr-notification-footer-spacer",
"cfr-notification-footer-learn-more-link",
"cfr-notification-footer-pintab-animation-container",
"cfr-notification-footer-pause-button",
];
const elementClassNames = [
"popup-notification-body-container",
];
beforeEach(() => {
@ -37,6 +43,7 @@ describe("CFRPageActions", () => {
fakeRecommendation = {
id: "fake_id",
content: {
category: "cfrDummy",
bucket_id: "fake_bucket_id",
notification_text: "Fake Notification Text",
info_icon: {
@ -52,6 +59,9 @@ describe("CFRPageActions", () => {
users: 1234,
amo_url: "a_path_to_amo",
},
descriptionDetails: {
steps: [{string_id: "cfr-features-step1"}],
},
text: "Here is the recommendation text body",
buttons: {
primary: {
@ -86,7 +96,7 @@ describe("CFRPageActions", () => {
globals = new GlobalOverrider();
globals.set({
Localization: class {},
DOMLocalization: class {},
promiseDocumentFlushed: sandbox.stub().callsFake(fn => Promise.resolve(fn())),
PopupNotifications: {
show: sandbox.stub(),
@ -103,9 +113,17 @@ describe("CFRPageActions", () => {
for (const id of elementIDs) {
const elem = document.createElement("div");
elem.setAttribute("id", id);
// TODO: Remove this once travis is on Firefox 63+
elem.toggleAttribute = () => {};
containerElem.appendChild(elem);
elements[id] = elem;
}
for (const className of elementClassNames) {
const elem = document.createElement("div");
elem.setAttribute("class", className);
containerElem.appendChild(elem);
elements[className] = elem;
}
});
afterEach(() => {
@ -341,7 +359,7 @@ describe("CFRPageActions", () => {
formatMessagesStub = sandbox.stub()
.withArgs({id: "hello_world"})
.resolves(localeStrings);
global.Localization.prototype.formatMessages = formatMessagesStub;
global.DOMLocalization.prototype.formatMessages = formatMessagesStub;
});
it("should return the argument if a string_id is not defined", async () => {
@ -398,6 +416,8 @@ describe("CFRPageActions", () => {
});
describe("#_showPopupOnClick", () => {
let translateElementsStub;
let setAttributesStub;
beforeEach(async () => {
CFRPageActions.PageActionMap.set(fakeBrowser.ownerGlobal, pageAction);
await CFRPageActions.addRecommendation(fakeBrowser, fakeHost, fakeRecommendation, dispatchStub);
@ -414,6 +434,11 @@ describe("CFRPageActions", () => {
.resolves("Learn more")
.withArgs(sinon.match({string_id: "cfr-doorhanger-extension-total-users"}))
.callsFake(async ({args}) => `${args.total} users`); // eslint-disable-line max-nested-callbacks
translateElementsStub = sandbox.stub().resolves();
setAttributesStub = sandbox.stub();
global.DOMLocalization.prototype.setAttributes = setAttributesStub;
global.DOMLocalization.prototype.translateElements = translateElementsStub;
});
it("should call `.hideAddressBarNotifier` and do nothing if there is no recommendation for the selected browser", async () => {
@ -591,6 +616,36 @@ describe("CFRPageActions", () => {
}
);
});
it("should show the bullet list details", async () => {
delete fakeRecommendation.content.addon;
await pageAction._showPopupOnClick();
assert.calledOnce(translateElementsStub);
});
it("should set the data-l10n-id on the list element", async () => {
delete fakeRecommendation.content.addon;
await pageAction._showPopupOnClick();
assert.calledOnce(setAttributesStub);
assert.calledWith(setAttributesStub, sinon.match.any, fakeRecommendation.content.descriptionDetails.steps[0].string_id);
});
it("should set the correct data-notification-category", async () => {
delete fakeRecommendation.content.addon;
await pageAction._showPopupOnClick();
assert.equal(elements["contextual-feature-recommendation-notification"].dataset.notificationCategory, fakeRecommendation.content.category);
});
it("should send PIN event on primary action click", async () => {
sandbox.stub(pageAction, "_sendTelemetry");
delete fakeRecommendation.content.addon;
await pageAction._showPopupOnClick();
const [, , , , {callback}] = global.PopupNotifications.show.firstCall.args;
callback();
// First call is triggered by `_showPopupOnClick`
assert.propertyVal(pageAction._sendTelemetry.secondCall.args[0], "event", "PIN");
});
});
});

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

@ -36,6 +36,9 @@ export class FakeRemotePageManager {
pinTab: sinon.stub(),
selectedTab: {},
},
ConfirmationHint: {
show: sinon.stub(),
},
},
};
this.portID = "6000:2";

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

@ -2,6 +2,7 @@ import {CFRMessageProvider} from "lib/CFRMessageProvider.jsm";
import schema from "content-src/asrouter/templates/CFR/templates/ExtensionDoorhanger.schema.json";
const DEFAULT_CONTENT = {
"category": "dummyCategory",
"bucket_id": "some_bucket_id",
"notification_text": "Recommendation",
"heading_text": "Recommended Extension",
@ -39,6 +40,7 @@ const DEFAULT_CONTENT = {
};
const L10N_CONTENT = {
"category": "dummyL10NCategory",
"bucket_id": "some_bucket_id",
"notification_text": {"string_id": "notification_text_id"},
"heading_text": {"string_id": "heading_text_id"},

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

@ -0,0 +1,39 @@
import {_DSLinkMenu as DSLinkMenu} from "content-src/components/DiscoveryStreamComponents/DSLinkMenu/DSLinkMenu";
import {LinkMenu} from "content-src/components/LinkMenu/LinkMenu";
import React from "react";
import {shallowWithIntl} from "test/unit/utils";
describe("<DSLinkMenu>", () => {
const ValidDSLinkMenuProps = {
site: {},
};
let wrapper;
beforeEach(() => {
wrapper = shallowWithIntl(<DSLinkMenu {...ValidDSLinkMenuProps} />);
});
it("should render a context menu button", () => {
assert.ok(wrapper.exists());
assert.ok(wrapper.find(".context-menu-button").exists());
});
it("should render LinkMenu when context menu button is clicked", () => {
let button = wrapper.find(".context-menu-button");
button.simulate("click", {preventDefault: () => {}});
assert.equal(wrapper.find(LinkMenu).length, 1);
});
it("should pass dispatch, onUpdate, onShow, site, options, source and index to LinkMenu", () => {
wrapper.find(".context-menu-button").simulate("click", {preventDefault: () => {}});
const linkMenuProps = wrapper.find(LinkMenu).props();
["dispatch", "onUpdate", "onShow", "site", "index", "options", "source"].forEach(prop => assert.property(linkMenuProps, prop));
});
it("should pass through the correct menu options to LinkMenu", () => {
wrapper.find(".context-menu-button").simulate("click", {preventDefault: () => {}});
const linkMenuProps = wrapper.find(LinkMenu).props();
assert.deepEqual(linkMenuProps.options,
["OpenInNewWindow", "OpenInPrivateWindow"]);
});
});

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

@ -34,6 +34,7 @@ const TEST_GLOBAL = {
},
AppConstants: {MOZILLA_OFFICIAL: true},
UpdateUtils: {getUpdateChannel() {}},
BrowserWindowTracker: {getTopWindow() {}},
ChromeUtils: {
defineModuleGetter() {},
generateQI() { return {}; },