Bug 1525452 - Add Message component, visibility capping and bug fixes to Activity Stream r=k88hudson

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ed Lee 2019-02-06 15:58:38 +00:00
Родитель d7fea3b29b
Коммит 8846c7f2ae
164 изменённых файлов: 1920 добавлений и 524 удалений

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

@ -47,6 +47,7 @@ function AboutNewTabService() {
// More initialization happens here
this.toggleActivityStream(true);
this.initialized = true;
this.alreadyRecordedTopsitesPainted = false;
if (IS_MAIN_PROCESS) {
AboutNewTab.init();
@ -331,6 +332,20 @@ AboutNewTabService.prototype = {
this.notifyChange();
},
maybeRecordTopsitesPainted(timestamp) {
if (this.alreadyRecordedTopsitesPainted) {
return;
}
const SCALAR_KEY = "timestamps.about_home_topsites_first_paint";
let startupInfo = Services.startup.getStartupInfo();
let processStartTs = startupInfo.process.getTime();
let delta = Math.round(timestamp - processStartTs);
Services.telemetry.scalarSet(SCALAR_KEY, delta);
this.alreadyRecordedTopsitesPainted = true;
},
uninit() {
if (!this.initialized) {
return;

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

@ -45,8 +45,10 @@ for (const type of [
"DISCOVERY_STREAM_FEEDS_UPDATE",
"DISCOVERY_STREAM_LAYOUT_RESET",
"DISCOVERY_STREAM_LAYOUT_UPDATE",
"DISCOVERY_STREAM_OPT_OUT",
"DISCOVERY_STREAM_SPOCS_ENDPOINT",
"DISCOVERY_STREAM_SPOCS_UPDATE",
"DISCOVERY_STREAM_SPOC_IMPRESSION",
"DOWNLOAD_CHANGED",
"FAKE_FOCUS_SEARCH",
"FILL_SEARCH_TERM",

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

@ -1,17 +1,19 @@
/* globals Services */
"use strict";
/* istanbul ignore if */
if (typeof ChromeUtils !== "undefined") {
// Use a var here instead of let outside to avoid creating a locally scoped
// variable that hides the global, which we modify for testing.
// eslint-disable-next-line no-var, vars-on-top
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
}
let usablePerfObj;
/* istanbul ignore if */
/* istanbul ignore else */
// eslint-disable-next-line block-scoped-var
if (typeof Services !== "undefined") {
// Borrow the high-resolution timer from the hidden window....
// eslint-disable-next-line block-scoped-var
usablePerfObj = Services.appShell.hiddenDOMWindow.performance;
} else if (typeof performance !== "undefined") {
// we must be running in content space

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

@ -17,9 +17,10 @@
"properties": {
"bucket_id": {
"type": "string",
"description": "Bucket identifier for the addon."
"description": "A bucket identifier for the addon. This is used in order to anonymize telemetry for history-sensitive targeting."
},
"notification_text": {
"description": "The text in the small blue chicklet that appears in the URL bar. This can be a reference to a localized string in Firefox or just a plain string.",
"oneOf": [
{
"type": "string",
@ -35,11 +36,11 @@
},
"required": ["string_id"]
}
],
"description": "Id of localized string or message override."
]
},
"info_icon": {
"type": "object",
"description": "The small icon displayed in the top right corner of the pop-over. Should be 19x19px, svg or png. Defaults to a small question mark." ,
"properties": {
"label": {
"oneOf": [
@ -79,6 +80,7 @@
}
},
"heading_text": {
"description": "The larger heading text displayed in the pop-over. This can be a reference to a localized string in Firefox or just a plain string.",
"oneOf": [
{
"type": "string",
@ -94,10 +96,10 @@
"required": ["string_id"],
"description": "Id of localized string for extension doorhanger title"
}
],
"description": "Id of localized string or message override."
]
},
"addon": {
"description": "Addon information including AMO URL.",
"type": "object",
"properties": {
"id": {
@ -119,6 +121,7 @@
]
},
"icon": {
"description": "The icon displayed in the pop-over. Should be 64x64px and png/svg.",
"allOf": [
{"$ref": "#/definitions/linkUrl"},
{"description": "Addon icon"}
@ -145,6 +148,7 @@
"required": ["title", "author", "icon", "amo_url"]
},
"text": {
"description": "The body text displayed in the pop-over. This can be a reference to a localized string in Firefox or just a plain string.",
"oneOf": [
{
"type": "string",
@ -160,10 +164,10 @@
},
"required": ["string_id"]
}
],
"description": "Id of localized string or message override."
]
},
"buttons": {
"description": "The label and functionality for the buttons in the pop-over.",
"type": "object",
"properties": {
"primary": {

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

@ -3,6 +3,7 @@ import {addLocaleData, injectIntl, IntlProvider} from "react-intl";
import {ASRouterAdmin} from "content-src/components/ASRouterAdmin/ASRouterAdmin";
import {ConfirmDialog} from "content-src/components/ConfirmDialog/ConfirmDialog";
import {connect} from "react-redux";
import {DarkModeMessage} from "content-src/components/DarkModeMessage/DarkModeMessage";
import {DiscoveryStreamBase} from "content-src/components/DiscoveryStreamBase/DiscoveryStreamBase";
import {ErrorBoundary} from "content-src/components/ErrorBoundary/ErrorBoundary";
import {ManualMigration} from "content-src/components/ManualMigration/ManualMigration";
@ -186,6 +187,7 @@ export class BaseContent extends React.PureComponent {
}
{isDiscoveryStream ? (
<ErrorBoundary className="borderless-error">
{prefs.darkModeMessage && <DarkModeMessage />}
<DiscoveryStreamBase />
</ErrorBoundary>) : <Sections />}
<PrefsButton onClick={this.openPreferences} />

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

@ -0,0 +1,40 @@
import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
import {connect} from "react-redux";
import React from "react";
export class _DarkModeMessage extends React.PureComponent {
constructor(props) {
super(props);
this.handleSwitch = this.handleSwitch.bind(this);
this.handleCancel = this.handleCancel.bind(this);
}
handleSwitch() {
// Switch to default new tab version
this.props.dispatch(ac.AlsoToMain({type: at.DISCOVERY_STREAM_OPT_OUT}));
}
handleCancel() {
// Capture user consent and not show dark mode message in future
this.props.dispatch(ac.SetPref("darkModeMessage", false));
}
render() {
return (<div className="ds-message-container">
<p>
<span className="icon icon-info" />
<span>This version of New Tab doesn not support dark mode yet.</span>
</p>
<div className="ds-message-actions actions">
<button onClick={this.handleCancel}>
<span>Got it</span>
</button>
<button className="dismiss" onClick={this.handleSwitch}>
<span>Use older version</span>
</button>
</div>
</div>);
}
}
export const DarkModeMessage = connect()(_DarkModeMessage);

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

@ -0,0 +1,48 @@
.ds-message-container {
display: none;
color: $grey-50;
font-size: 13px;
justify-content: center;
margin: 0 auto 40px;
width: 936px;
p {
margin: 0;
align-self: center;
line-height: 20px;
display: flex;
}
.icon {
align-self: center;
fill: var(--newtab-icon-secondary-color);
margin-inline-end: 6px;
width: 20px;
height: 20px;
}
.ds-message-actions {
align-self: center;
border: 0;
padding: 0;
button {
height: 24px;
margin: 0;
margin-inline-start: 20px;
padding: 0 20px;
&.dismiss {
padding: 0;
}
}
}
}
.force-light-theme {
&[lwt-newtab-brighttext] {
.ds-message-container {
display: flex;
}
}
}

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

@ -1,5 +1,6 @@
import {CardGrid} from "content-src/components/DiscoveryStreamComponents/CardGrid/CardGrid";
import {connect} from "react-redux";
import {DSMessage} from "content-src/components/DiscoveryStreamComponents/DSMessage/DSMessage";
import {Hero} from "content-src/components/DiscoveryStreamComponents/Hero/Hero";
import {HorizontalRule} from "content-src/components/DiscoveryStreamComponents/HorizontalRule/HorizontalRule";
import {ImpressionStats} from "content-src/components/DiscoveryStreamImpressionStats/ImpressionStats";
@ -11,14 +12,14 @@ import {selectLayoutRender} from "content-src/lib/selectLayoutRender";
import {TopSites} from "content-src/components/DiscoveryStreamComponents/TopSites/TopSites";
// According to the Pocket API endpoint specs, `component.properties.items` is a required property with following values:
// - List 1-6 items
// - List 1-12 items
// - Hero 1-5 items
// - CardGrid 1-8 items
// - CardGrid 1-16 items
// To enforce that, we define various maximium items for individual components as an extra check.
// Note that these values are subject to the future changes of the specs.
const MAX_ROWS_HERO = 5;
const MAX_ROWS_LIST = 6;
const MAX_ROWS_CARDGRID = 8;
const MAX_ROWS_LIST = 12;
const MAX_ROWS_CARDGRID = 16;
const ALLOWED_CSS_URL_PREFIXES = ["chrome://", "resource://", "https://img-getpocket.cdn.mozilla.net/"];
const DUMMY_CSS_SELECTOR = "DUMMY#CSS.SELECTOR";
@ -127,6 +128,15 @@ export class _DiscoveryStreamBase extends React.PureComponent {
switch (component.type) {
case "TopSites":
return (<TopSites header={component.header} />);
case "Message":
return (
<DSMessage
title={component.header && component.header.title}
subtitle={component.header && component.header.subtitle}
link_text={component.header && component.header.link_text}
link_url={component.header && component.header.link_url}
icon={component.header && component.header.icon} />
);
case "SectionTitle":
return (
<SectionTitle

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

@ -14,6 +14,7 @@ export class CardGrid extends React.PureComponent {
let cards = data.recommendations.slice(0, this.props.items).map((rec, index) => (
<DSCard
campaignId={rec.campaign_id}
key={`dscard-${index}`}
image_src={rec.image_src}
title={rec.title}

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

@ -1,12 +1,65 @@
import {actionCreators as ac} from "common/Actions.jsm";
import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
import React from "react";
const VISIBLE = "visible";
const VISIBILITY_CHANGE_EVENT = "visibilitychange";
const INTERSECTION_RATIO = 0.5;
export class DSCard extends React.PureComponent {
constructor(props) {
super(props);
this.cardElementRef = this.cardElementRef.bind(this);
this.onLinkClick = this.onLinkClick.bind(this);
}
componentDidMount() {
if (this.props.document.visibilityState === VISIBLE) {
this.setupIntersectionObserver();
} else {
this._onVisibilityChange = () => {
if (this.props.document.visibilityState === VISIBLE) {
this.setupIntersectionObserver();
this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
}
};
this.props.document.addEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
}
}
componentWillUnmount() {
if (this._onVisibilityChange) {
this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
}
if (this._intersectionObserver) {
this._intersectionObserver.unobserve(this.cardElement);
}
}
setupIntersectionObserver() {
const options = {threshold: INTERSECTION_RATIO};
this._intersectionObserver = new IntersectionObserver(entries => {
for (let entry of entries) {
if (entry.isIntersecting && entry.intersectionRatio >= INTERSECTION_RATIO) {
this.dispatchSpocImpression();
break;
}
}
}, options);
this._intersectionObserver.observe(this.cardElement);
}
dispatchSpocImpression() {
if (this.props.campaignId) {
this.props.dispatch(ac.OnlyToMain({type: at.DISCOVERY_STREAM_SPOC_IMPRESSION, data: {campaignId: this.props.campaignId}}));
}
this._intersectionObserver.unobserve(this.cardElement);
}
cardElementRef(element) {
this.cardElement = element;
}
onLinkClick(event) {
if (this.props.dispatch) {
this.props.dispatch(ac.UserEvent({
@ -25,7 +78,7 @@ export class DSCard extends React.PureComponent {
render() {
return (
<a href={this.props.url} className="ds-card" onClick={this.onLinkClick}>
<a href={this.props.url} className="ds-card" onClick={this.onLinkClick} ref={this.cardElementRef}>
<div className="img-wrapper">
<div className="img" style={{backgroundImage: `url(${this.props.image_src}`}} />
</div>
@ -48,3 +101,7 @@ export class DSCard extends React.PureComponent {
);
}
}
DSCard.defaultProps = {
document: global.document,
};

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

@ -0,0 +1,26 @@
import React from "react";
export class DSMessage extends React.PureComponent {
render() {
let hasSubtitleAndOrLink = this.props.link_text && this.props.link_url;
hasSubtitleAndOrLink = hasSubtitleAndOrLink || this.props.subtitle;
return (
<div className="ds-message">
{this.props.title && (
<header className="title">
{this.props.icon && (<img src={this.props.icon} />)}
<span>{this.props.title}</span>
</header>
)}
{ hasSubtitleAndOrLink && (
<p className="subtitle">
{this.props.subtitle && (<span>{this.props.subtitle}</span>)}
{this.props.link_text && this.props.link_url && (<a href={this.props.link_url}>{this.props.link_text}</a>)}
</p>
)}
<hr className="ds-hr" />
</div>
);
}
}

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

@ -0,0 +1,41 @@
.ds-message {
margin: 8px 0 0;
.title {
display: flex;
align-items: center;
img {
width: 16px;
height: 16px;
margin: 0 6px 0 0;
}
span {
line-height: 24px;
font-size: 17px;
color: $grey-90;
font-weight: 600;
}
}
.subtitle {
line-height: 20px;
font-size: 14px;
color: $grey-50;
margin: 0;
span::after {
content: ' ';
}
a:hover,
a:focus {
text-decoration: underline;
}
}
.ds-hr {
margin: 16px 0 8px;
}
}

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

@ -2,7 +2,6 @@ import {actionCreators as ac} from "common/Actions.jsm";
import {DSCard} from "../DSCard/DSCard.jsx";
import {List} from "../List/List.jsx";
import React from "react";
import {truncateText} from "content-src/lib/truncate-text";
export class Hero extends React.PureComponent {
constructor(props) {
@ -42,16 +41,17 @@ export class Hero extends React.PureComponent {
// Note that `{index + 1}` is necessary below for telemetry since we treat heroRec as index 0.
let cards = otherRecs.map((rec, index) => (
<DSCard
campaignId={rec.campaign_id}
key={`dscard-${index}`}
image_src={rec.image_src}
title={truncateText(rec.title, 44)}
title={rec.title}
url={rec.url}
id={rec.id}
index={index + 1}
type={this.props.type}
dispatch={this.props.dispatch}
context={truncateText(rec.context, 22)}
source={truncateText(rec.domain, 22)} />
context={rec.context}
source={rec.domain} />
));
let list = (
@ -73,12 +73,12 @@ export class Hero extends React.PureComponent {
<div className="img" style={{backgroundImage: `url(${heroRec.image_src})`}} />
</div>
<div className="meta">
<header>{truncateText(heroRec.title, 28)}</header>
<p>{truncateText(heroRec.excerpt, 114)}</p>
<header>{heroRec.title}</header>
<p>{heroRec.excerpt}</p>
{heroRec.context ? (
<p className="context">{truncateText(heroRec.context, 22)}</p>
<p className="context">{heroRec.context}</p>
) : (
<p className="source">{truncateText(heroRec.domain, 22)}</p>
<p className="source">{heroRec.domain}</p>
)}
</div>
</a>

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

@ -1,7 +1,6 @@
import {actionCreators as ac} from "common/Actions.jsm";
import {connect} from "react-redux";
import React from "react";
import {truncateText} from "content-src/lib/truncate-text";
/**
* @note exported for testing only
@ -36,7 +35,7 @@ export class ListItem extends React.PureComponent {
<a className="ds-list-item-link" href={this.props.url} onClick={this.onLinkClick}>
<div className="ds-list-item-text">
<div className="ds-list-item-title">{this.props.title}</div>
{this.props.excerpt && <div className="ds-list-item-excerpt">{truncateText(this.props.excerpt, 90)}</div>}
{this.props.excerpt && <div className="ds-list-item-excerpt">{this.props.excerpt}</div>}
<div className="ds-list-item-info">{this.props.domain}</div>
</div>
<div className="ds-list-image" style={{backgroundImage: `url(${this.props.image_src})`}} />

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

@ -1,3 +0,0 @@
export function truncateText(text = "", cap) {
return text.substring(0, cap).trim() + (text.length > cap ? "…" : "");
}

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

@ -145,6 +145,7 @@ input {
@import '../components/PocketLoggedInCta/PocketLoggedInCta';
@import '../components/MoreRecommendations/MoreRecommendations';
@import '../components/DiscoveryStreamBase/DiscoveryStreamBase';
@import '../components/DarkModeMessage/DarkModeMessage';
// Discovery Stream Components
@import '../components/DiscoveryStreamComponents/CardGrid/CardGrid';
@ -155,6 +156,7 @@ input {
@import '../components/DiscoveryStreamComponents/SectionTitle/SectionTitle';
@import '../components/DiscoveryStreamComponents/TopSites/TopSites';
@import '../components/DiscoveryStreamComponents/DSCard/DSCard';
@import '../components/DiscoveryStreamComponents/DSMessage/DSMessage';
// AS Router
@import '../asrouter/components/Button/Button';

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

@ -1831,6 +1831,39 @@ main {
color: #0C0C0D;
margin: 16px 0; }
.ds-message-container {
display: none;
color: #737373;
font-size: 13px;
justify-content: center;
margin: 0 auto 40px;
width: 936px; }
.ds-message-container p {
margin: 0;
align-self: center;
line-height: 20px;
display: flex; }
.ds-message-container .icon {
align-self: center;
fill: var(--newtab-icon-secondary-color);
margin-inline-end: 6px;
width: 20px;
height: 20px; }
.ds-message-container .ds-message-actions {
align-self: center;
border: 0;
padding: 0; }
.ds-message-container .ds-message-actions button {
height: 24px;
margin: 0;
margin-inline-start: 20px;
padding: 0 20px; }
.ds-message-container .ds-message-actions button.dismiss {
padding: 0; }
.force-light-theme[lwt-newtab-brighttext] .ds-message-container {
display: flex; }
.ds-card-grid {
display: grid;
grid-gap: 24px; }
@ -2339,6 +2372,33 @@ main {
.ds-card .context {
color: #008EA4; }
.ds-message {
margin: 8px 0 0; }
.ds-message .title {
display: flex;
align-items: center; }
.ds-message .title img {
width: 16px;
height: 16px;
margin: 0 6px 0 0; }
.ds-message .title span {
line-height: 24px;
font-size: 17px;
color: #0C0C0D;
font-weight: 600; }
.ds-message .subtitle {
line-height: 20px;
font-size: 14px;
color: #737373;
margin: 0; }
.ds-message .subtitle span::after {
content: ' '; }
.ds-message .subtitle a:hover,
.ds-message .subtitle a:focus {
text-decoration: underline; }
.ds-message .ds-hr {
margin: 16px 0 8px; }
.ASRouterButton {
font-weight: 600;
font-size: 14px;

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -1834,6 +1834,39 @@ main {
color: #0C0C0D;
margin: 16px 0; }
.ds-message-container {
display: none;
color: #737373;
font-size: 13px;
justify-content: center;
margin: 0 auto 40px;
width: 936px; }
.ds-message-container p {
margin: 0;
align-self: center;
line-height: 20px;
display: flex; }
.ds-message-container .icon {
align-self: center;
fill: var(--newtab-icon-secondary-color);
margin-inline-end: 6px;
width: 20px;
height: 20px; }
.ds-message-container .ds-message-actions {
align-self: center;
border: 0;
padding: 0; }
.ds-message-container .ds-message-actions button {
height: 24px;
margin: 0;
margin-inline-start: 20px;
padding: 0 20px; }
.ds-message-container .ds-message-actions button.dismiss {
padding: 0; }
.force-light-theme[lwt-newtab-brighttext] .ds-message-container {
display: flex; }
.ds-card-grid {
display: grid;
grid-gap: 24px; }
@ -2342,6 +2375,33 @@ main {
.ds-card .context {
color: #008EA4; }
.ds-message {
margin: 8px 0 0; }
.ds-message .title {
display: flex;
align-items: center; }
.ds-message .title img {
width: 16px;
height: 16px;
margin: 0 6px 0 0; }
.ds-message .title span {
line-height: 24px;
font-size: 17px;
color: #0C0C0D;
font-weight: 600; }
.ds-message .subtitle {
line-height: 20px;
font-size: 14px;
color: #737373;
margin: 0; }
.ds-message .subtitle span::after {
content: ' '; }
.ds-message .subtitle a:hover,
.ds-message .subtitle a:focus {
text-decoration: underline; }
.ds-message .ds-hr {
margin: 16px 0 8px; }
.ASRouterButton {
font-weight: 600;
font-size: 14px;

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -1831,6 +1831,39 @@ main {
color: #0C0C0D;
margin: 16px 0; }
.ds-message-container {
display: none;
color: #737373;
font-size: 13px;
justify-content: center;
margin: 0 auto 40px;
width: 936px; }
.ds-message-container p {
margin: 0;
align-self: center;
line-height: 20px;
display: flex; }
.ds-message-container .icon {
align-self: center;
fill: var(--newtab-icon-secondary-color);
margin-inline-end: 6px;
width: 20px;
height: 20px; }
.ds-message-container .ds-message-actions {
align-self: center;
border: 0;
padding: 0; }
.ds-message-container .ds-message-actions button {
height: 24px;
margin: 0;
margin-inline-start: 20px;
padding: 0 20px; }
.ds-message-container .ds-message-actions button.dismiss {
padding: 0; }
.force-light-theme[lwt-newtab-brighttext] .ds-message-container {
display: flex; }
.ds-card-grid {
display: grid;
grid-gap: 24px; }
@ -2339,6 +2372,33 @@ main {
.ds-card .context {
color: #008EA4; }
.ds-message {
margin: 8px 0 0; }
.ds-message .title {
display: flex;
align-items: center; }
.ds-message .title img {
width: 16px;
height: 16px;
margin: 0 6px 0 0; }
.ds-message .title span {
line-height: 24px;
font-size: 17px;
color: #0C0C0D;
font-weight: 600; }
.ds-message .subtitle {
line-height: 20px;
font-size: 14px;
color: #737373;
margin: 0; }
.ds-message .subtitle span::after {
content: ' '; }
.ds-message .subtitle a:hover,
.ds-message .subtitle a:focus {
text-decoration: underline; }
.ds-message .ds-hr {
margin: 16px 0 8px; }
.ASRouterButton {
font-weight: 600;
font-size: 14px;

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -91,7 +91,7 @@ module.exports = function(config) {
options: {
plugins: [
// Converts .jsm files into common-js modules
["jsm-to-commonjs", {basePath: PATHS.resourcePathRegEx, replace: true}], // require("babel-plugin-jsm-to-commonjs")
["jsm-to-commonjs", {basePath: PATHS.resourcePathRegEx, removeOtherImports: true, replace: true}], // require("babel-plugin-jsm-to-commonjs")
["transform-async-to-module-method", {module: "co-task", method: "async"}], // require("babel-plugin-transform-async-to-module-method")
"transform-es2015-modules-commonjs", // require("babel-plugin-transform-es2015-modules-commonjs")
["transform-object-rest-spread", {"useBuiltIns": true}], // require("babel-plugin-transform-object-rest-spread")

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

@ -246,9 +246,8 @@ const MessageLoaderUtils = {
const aUri = Services.io.newURI(url);
const systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
// AddonManager installation source associated to the addons installed from activitystream
// (See Bug 1496167 for a rationale).
const telemetryInfo = {source: "activitystream"};
// AddonManager installation source associated to the addons installed from activitystream's CFR
const telemetryInfo = {source: "amo"};
const install = await AddonManager.getInstallForURL(aUri.spec, {telemetryInfo});
await AddonManager.installAddonFromWebpage("application/x-xpinstall", browser,
systemPrincipal, install);

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

@ -287,6 +287,7 @@ this.AboutPreferences = class AboutPreferences {
createAppend("hbox", discoveryGroup)
.appendChild(contentDiscoveryButton)
.addEventListener("click", async () => {
this.store.dispatch({type: at.DISCOVERY_STREAM_OPT_OUT});
const activeExperiments = await PreferenceExperiments.getAllActive();
const experiment = activeExperiments.find(exp => exp.preferenceName === DISCOVERY_STREAM_CONFIG_PREF_NAME);
// Unconditionally update the UI for a fast user response and in

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

@ -222,6 +222,14 @@ const PREFS_CONFIG = new Map([
layout_endpoint: "https://getpocket.com/v3/newtab/layout?version=1&consumer_key=40249-e88c401e1b1f2242d9e441c4&layout_variant=basic",
}),
}],
["discoverystream.optOut.0", {
title: "Opt out of new layout v0",
value: false,
}],
["darkModeMessage", {
title: "Boolean flag that decides whether to show the dark Mode message or not.",
value: IS_NIGHTLY_OR_UNBRANDED_BUILD,
}],
]);
// Array of each feed's FEEDS_CONFIG factory and values to add to PREFS_CONFIG

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

@ -5,7 +5,6 @@
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]);
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const {actionTypes: at, actionCreators: ac} = ChromeUtils.import("resource://activity-stream/common/Actions.jsm");
const {PersistentCache} = ChromeUtils.import("resource://activity-stream/lib/PersistentCache.jsm");
@ -14,7 +13,11 @@ const CACHE_KEY = "discovery_stream";
const LAYOUT_UPDATE_TIME = 30 * 60 * 1000; // 30 minutes
const COMPONENT_FEEDS_UPDATE_TIME = 30 * 60 * 1000; // 30 minutes
const SPOCS_FEEDS_UPDATE_TIME = 30 * 60 * 1000; // 30 minutes
const CONFIG_PREF_NAME = "browser.newtabpage.activity-stream.discoverystream.config";
const MAX_LIFETIME_CAP = 500; // Guard against misconfiguration on the server
const PREF_CONFIG = "discoverystream.config";
const PREF_OPT_OUT = "discoverystream.optOut.0";
const PREF_SHOW_SPONSORED = "showSponsored";
const PREF_SPOC_IMPRESSIONS = "discoverystream.spoc.impressions";
this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
constructor() {
@ -32,41 +35,35 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
return this._prefCache.config;
}
try {
this._prefCache.config = JSON.parse(Services.prefs.getStringPref(CONFIG_PREF_NAME, ""));
this._prefCache.config = JSON.parse(this.store.getState().Prefs.values[PREF_CONFIG]);
// Modify the cached config with the user set opt-out for other consumers
this._prefCache.config.enabled = this._prefCache.config.enabled &&
!this.store.getState().Prefs.values[PREF_OPT_OUT];
} catch (e) {
// istanbul ignore next
this._prefCache.config = {};
// istanbul ignore next
Cu.reportError(`Could not parse preference. Try resetting ${CONFIG_PREF_NAME} in about:config.`);
Cu.reportError(`Could not parse preference. Try resetting ${PREF_CONFIG} in about:config.`);
}
return this._prefCache.config;
}
get showSpocs() {
// showSponsored is generally a use set spoc opt out,
// show_spocs is generally a mozilla set value.
return this.store.getState().Prefs.values.showSponsored && this.config.show_spocs;
// Combine user-set sponsored opt-out with Mozilla-set config
return this.store.getState().Prefs.values[PREF_SHOW_SPONSORED] && this.config.show_spocs;
}
setupPrefs() {
Services.prefs.addObserver(CONFIG_PREF_NAME, this);
// Send the initial state of the pref on our reducer
this.store.dispatch(ac.BroadcastToContent({type: at.DISCOVERY_STREAM_CONFIG_SETUP, data: this.config}));
}
uninitPrefs() {
Services.prefs.removeObserver(CONFIG_PREF_NAME, this);
// Reset in-memory cache
this._prefCache = {};
}
observe(aSubject, aTopic, aPrefName) {
if (aPrefName === CONFIG_PREF_NAME) {
this._prefCache.config = null;
this.store.dispatch(ac.BroadcastToContent({type: at.DISCOVERY_STREAM_CONFIG_CHANGE, data: this.config}));
}
}
async fetchFromEndpoint(endpoint) {
if (!endpoint) {
Cu.reportError("Tried to fetch endpoint but none was configured.");
@ -183,6 +180,8 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
lastUpdated: Date.now(),
data: spocsResponse,
};
this.cleanUpCampaignImpressionPref(spocs.data);
await this.cache.set("spocs", spocs);
} else {
Cu.reportError("No response for spocs_endpoint prop");
@ -203,11 +202,62 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
type: at.DISCOVERY_STREAM_SPOCS_UPDATE,
data: {
lastUpdated: spocs.lastUpdated,
spocs: spocs.data,
spocs: this.filterSpocs(spocs.data),
},
});
}
// Filter spocs based on frequency caps
filterSpocs(data) {
if (data && data.spocs && data.spocs.length) {
const {spocs} = data;
const impressions = this.readImpressionsPref(PREF_SPOC_IMPRESSIONS);
return {
...data,
spocs: spocs.filter(s => this.isBelowFrequencyCap(impressions, s)),
};
}
return data;
}
// Frequency caps are based on campaigns, which may include multiple spocs.
// We currently support two types of frequency caps:
// - lifetime: Indicates how many times spocs from a campaign can be shown in total
// - period: Indicates how many times spocs from a campaign can be shown within a period
//
// So, for example, the feed configuration below defines that for campaign 1 no more
// than 5 spocs can be shown in total, and no more than 2 per hour.
// "campaign_id": 1,
// "caps": {
// "lifetime": 5,
// "campaign": {
// "count": 2,
// "period": 3600
// }
// }
isBelowFrequencyCap(impressions, spoc) {
const campaignImpressions = impressions[spoc.campaign_id];
if (!campaignImpressions) {
return true;
}
const lifetime = spoc.caps && spoc.caps.lifetime;
const lifeTimeCap = Math.min(lifetime || MAX_LIFETIME_CAP, MAX_LIFETIME_CAP);
const lifeTimeCapExceeded = campaignImpressions.length >= lifeTimeCap;
if (lifeTimeCapExceeded) {
return false;
}
const campaignCap = spoc.caps && spoc.caps.campaign;
if (campaignCap) {
const campaignCapExceeded = campaignImpressions
.filter(i => (Date.now() - i) < (campaignCap.period * 1000)).length >= campaignCap.count;
return !campaignCapExceeded;
}
return true;
}
async getComponentFeed(feedUrl) {
const cachedData = await this.cache.get() || {};
const {feeds} = cachedData;
@ -277,6 +327,50 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
}
}
recordCampaignImpression(campaignId) {
let impressions = this.readImpressionsPref(PREF_SPOC_IMPRESSIONS);
const timeStamps = impressions[campaignId] || [];
timeStamps.push(Date.now());
impressions = {...impressions, [campaignId]: timeStamps};
this.writeImpressionsPref(PREF_SPOC_IMPRESSIONS, impressions);
}
cleanUpCampaignImpressionPref(data) {
if (data.spocs && data.spocs.length) {
const campaignIds = data.spocs.map(s => `${s.campaign_id}`);
this.cleanUpImpressionPref(id => !campaignIds.includes(id), PREF_SPOC_IMPRESSIONS);
}
}
writeImpressionsPref(pref, impressions) {
this.store.dispatch(ac.SetPref(pref, JSON.stringify(impressions)));
}
readImpressionsPref(pref) {
const prefVal = this.store.getState().Prefs.values[pref];
return prefVal ? JSON.parse(prefVal) : {};
}
cleanUpImpressionPref(isExpired, pref) {
const impressions = this.readImpressionsPref(pref);
let changed = false;
Object
.keys(impressions)
.forEach(id => {
if (isExpired(id)) {
changed = true;
delete impressions[id];
}
});
if (changed) {
this.writeImpressionsPref(pref, impressions);
}
}
async onAction(action) {
switch (action.type) {
case at.INIT:
@ -295,20 +389,60 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
}
break;
case at.DISCOVERY_STREAM_CONFIG_SET_VALUE:
Services.prefs.setStringPref(CONFIG_PREF_NAME, JSON.stringify({...this.config, [action.data.name]: action.data.value}));
// Disable opt-out if we're explicitly trying to enable
if (action.data.name === "enabled" && action.data.value) {
this.store.dispatch(ac.SetPref(PREF_OPT_OUT, false));
}
// Use the original string pref to then set a value instead of
// this.config which has some modifications
this.store.dispatch(ac.SetPref(PREF_CONFIG, JSON.stringify({
...JSON.parse(this.store.getState().Prefs.values[PREF_CONFIG]),
[action.data.name]: action.data.value,
})));
break;
case at.DISCOVERY_STREAM_CONFIG_CHANGE:
// When the config pref changes, load or unload data as needed.
await this.onPrefChange();
break;
case at.DISCOVERY_STREAM_OPT_OUT:
this.store.dispatch(ac.SetPref(PREF_OPT_OUT, true));
break;
case at.DISCOVERY_STREAM_SPOC_IMPRESSION:
if (this.showSpocs) {
this.recordCampaignImpression(action.data.campaignId);
const cachedData = await this.cache.get() || {};
const {spocs} = cachedData;
this.store.dispatch(ac.AlsoToPreloaded({
type: at.DISCOVERY_STREAM_SPOCS_UPDATE,
data: {
lastUpdated: spocs.lastUpdated,
spocs: this.filterSpocs(spocs.data),
},
}));
}
break;
case at.UNINIT:
// When this feed is shutting down:
this.uninitPrefs();
break;
case at.PREF_CHANGED:
// Check if spocs was disabled. Remove them if they were.
if (action.data.name === "showSponsored") {
await this.loadSpocs();
switch (action.data.name) {
case PREF_CONFIG:
case PREF_OPT_OUT:
// Clear the cached config and broadcast the newly computed value
this._prefCache.config = null;
this.store.dispatch(ac.BroadcastToContent({
type: at.DISCOVERY_STREAM_CONFIG_CHANGE,
data: this.config,
}));
break;
// Check if spocs was disabled. Remove them if they were.
case PREF_SHOW_SPONSORED:
await this.loadSpocs();
break;
}
break;
}

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

@ -622,6 +622,15 @@ this.TelemetryFeed = class TelemetryFeed {
this.setLoadTriggerInfo(port);
}
let timestamp = data.topsites_first_painted_ts;
if (timestamp &&
session.page === "about:home" &&
!HomePage.overridden &&
Services.prefs.getIntPref("browser.startup.page") === 1) {
aboutNewTabService.maybeRecordTopsitesPainted(timestamp);
}
Object.assign(session.perf, data);
}

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

@ -25,6 +25,7 @@ const STORIES_NOW_THRESHOLD = 24 * 60 * 60 * 1000; // 24 hours
const MIN_DOMAIN_AFFINITIES_UPDATE_TIME = 12 * 60 * 60 * 1000; // 12 hours
const DEFAULT_RECS_EXPIRE_TIME = 60 * 60 * 1000; // 1 hour
const SECTION_ID = "topstories";
const IMPRESSION_SOURCE = "TOP_STORIES";
const SPOC_IMPRESSION_TRACKING_PREF = "feeds.section.topstories.spoc.impressions";
const REC_IMPRESSION_TRACKING_PREF = "feeds.section.topstories.rec.impressions";
const OPTIONS_PREF = "feeds.section.topstories.options";
@ -656,21 +657,27 @@ this.TopStoriesFeed = class TopStoriesFeed {
}
break;
case at.TELEMETRY_IMPRESSION_STATS: {
const payload = action.data;
const viewImpression = !("click" in payload || "block" in payload || "pocket" in payload);
if (payload.tiles && viewImpression) {
if (this.shouldShowSpocs()) {
payload.tiles.forEach(t => {
if (this.spocCampaignMap.has(t.id)) {
this.recordCampaignImpression(this.spocCampaignMap.get(t.id));
}
});
}
if (this.personalized) {
const topRecs = payload.tiles
.filter(t => !this.spocCampaignMap.has(t.id))
.map(t => t.id);
this.recordTopRecImpressions(topRecs);
// We want to make sure we only track impressions from Top Stories,
// otherwise unexpected things that are not properly handled can happen.
// Example: Impressions from spocs on Discovery Stream can cause the
// Top Stories impressions pref to continuously grow, see bug #1523408
if (action.data.source === IMPRESSION_SOURCE) {
const payload = action.data;
const viewImpression = !("click" in payload || "block" in payload || "pocket" in payload);
if (payload.tiles && viewImpression) {
if (this.shouldShowSpocs()) {
payload.tiles.forEach(t => {
if (this.spocCampaignMap.has(t.id)) {
this.recordCampaignImpression(this.spocCampaignMap.get(t.id));
}
});
}
if (this.personalized) {
const topRecs = payload.tiles
.filter(t => !this.spocCampaignMap.has(t.id))
.map(t => t.id);
this.recordTopRecImpressions(topRecs);
}
}
}
break;

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

@ -203,3 +203,4 @@ firstrun_skip_login=Kal citep man
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Yab jami ayera
section_menu_action_add_search_engine=Med Ingin me Yeny

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

@ -90,7 +90,12 @@ section_disclaimer_topstories_buttontext=حسنًا، فهمت
# sidebar mozilla-central string for the panel that has preferences related to
# what is shown for the homepage, new windows, and new tabs.
prefs_home_header=محتوى فَيَرفُكس الرئيسي
prefs_home_description=اختر المحتوى الذي تريد عرضه في شاشة فَيَرفُكس الرئيسية.
prefs_home_description=اختر المحتوى الذي تريد عرضه في شاشة بداية فَيَرفُكس.
prefs_content_discovery_header=شاشة بداية فَيَرفُكس
prefs_content_discovery_description=تتيح لك ميزة ”اكتشاف المحتوى“ في صفحة بداية فَيَرفُكس رؤية مقالات عالية الجودة لها علاقة بما تتابع، تأتيك من أرجاء الوِب.
prefs_content_discovery_button=عطّل اكتشاف المحتوى
# 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 +149,6 @@ pocket_read_more=المواضيع الشائعة:
# end of the list of popular topic links.
pocket_read_even_more=اعرض المزيد من الأخبار
pocket_more_reccommendations=مقترحات أخرى
pocket_learn_more=اطّلع على المزيد
pocket_how_it_works=آلية العمل
pocket_cta_button=نزِّل بوكِت
pocket_cta_text=احفظ القصص التي تحبّها في بوكِت، وزوّد عقلك بمقالات رائعة.
@ -209,3 +213,4 @@ firstrun_skip_login=تجاوز هذه الخطوة
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=افتح القائمة
section_menu_action_add_search_engine=أضِف محرك بحث

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

@ -213,3 +213,4 @@ firstrun_skip_login=Bu addımı keç
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Menyunu aç
section_menu_action_add_search_engine=Axtarış mühərriyi əlavə et

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

@ -91,6 +91,11 @@ section_disclaimer_topstories_buttontext=Зразумела
# what is shown for the homepage, new windows, and new tabs.
prefs_home_header=Хатні экран Firefox
prefs_home_description=Выберыце пажаданае змесціва для хатняга экрана Firefox.
prefs_content_discovery_header=Хатняя старонка Firefox
prefs_content_discovery_description=Выяўленне змесціва на хатняй старонцы Firefox дазволіць вам знаходзіць высакаякасныя рэлевантныя артыкулы з усяго сеціва.
prefs_content_discovery_button=Адключыць выяўленне змесціва
# 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 +149,6 @@ pocket_read_more=Папулярныя тэмы:
# end of the list of popular topic links.
pocket_read_even_more=Іншыя навіны
pocket_more_reccommendations=Больш рэкамендацый
pocket_learn_more=Падрабязней
pocket_how_it_works=Як гэта працуе
pocket_cta_button=Атрымаць Pocket
pocket_cta_text=Захоўвайце ўлюбёныя гісторыі ў Pocket, і сілкуйце свой розум добрай чытанкай.
@ -209,3 +213,4 @@ firstrun_skip_login=Прапусціць гэты крок
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Адкрыць меню
section_menu_action_add_search_engine=Дадаць пашукавік

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

@ -206,3 +206,4 @@ firstrun_privacy_notice=политиката за лични данни
firstrun_continue_to_login=Продължаване
firstrun_skip_login=Пропускане
section_menu_action_add_search_engine=Добавяне на търсеща машина

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

@ -208,3 +208,4 @@ firstrun_skip_login=এই ধাপটি বাদ দিন
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=মেনু খুলুন
section_menu_action_add_search_engine=অনুসন্ধান ইঞ্জিন যোগ

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

@ -209,3 +209,4 @@ firstrun_skip_login=ধাপটি উপেক্ষা করুন
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=মেনু খুলুন
section_menu_action_add_search_engine=অনুসন্ধান ইঞ্জিন যোগ করুন

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

@ -91,6 +91,9 @@ section_disclaimer_topstories_buttontext=Mat eo, komprenet am eus
# what is shown for the homepage, new windows, and new tabs.
prefs_home_header=Endalc'had Degemer Firefox
prefs_home_description=Dibabit peseurt endalc'had a fell deoc'h kaout war ho skramm Firefox Degemer.
prefs_content_discovery_header=Degemer 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=Danvezioù brudet:
# end of the list of popular topic links.
pocket_read_even_more=Gwelet muioc'h a istorioù
pocket_more_reccommendations=Erbedadennoù ouzhpenn
pocket_learn_more=Gouzout hiroc'h
pocket_how_it_works=Penaos ez a en-dro
pocket_cta_button=Staliañ Pocket
pocket_cta_text=Enrollit pennadoù a-zoare e Pocket ha magit ho spered gant lennadennoù boemus.
@ -209,3 +211,4 @@ firstrun_skip_login=Tremen ar bazenn-mañ
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Digeriñ al lañser
section_menu_action_add_search_engine=Ouzhpennañ ul lusker enklask

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

@ -213,3 +213,4 @@ firstrun_skip_login=Omet aquest pas
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Obre el menú
section_menu_action_add_search_engine=Afegeix un motor de cerca

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

@ -93,6 +93,8 @@ prefs_home_header=Etamab'äl pa ri Rutikirib'al Firefox
prefs_home_description=Tacha' achike etamab'äl nawajo' pa ri Rutikirib'al Firefox ruwäch.
prefs_content_discovery_header=Rutikirib'al Firefox
prefs_content_discovery_description=Content Discovery pa Rutikirib'al Firefox nuya' q'ij chawe richin ye'awïl nima'q taq cholna'oj ri nïm kejqalem pa ronojel ajk'amaya'l.
prefs_content_discovery_button=Tichup Content Discovery
# 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).
@ -211,3 +213,4 @@ firstrun_skip_login=Tixakalüx re jun ruxak re'
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Tijaq k'utüy samaj
section_menu_action_add_search_engine=Titz'aqatisäx Kanob'äl

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

@ -213,3 +213,4 @@ firstrun_skip_login=Přeskočit tento krok
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Otevře nabídku
section_menu_action_add_search_engine=Přidat vyhledávač

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

@ -213,3 +213,4 @@ firstrun_skip_login=Hepgor y cam hwn
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Agor y ddewislen
section_menu_action_add_search_engine=Ychwanegu Peiriant Chwilio

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

@ -218,7 +218,7 @@ firstrun_invalid_input=En gyldig mailadresse er påkrævet
# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
firstrun_extra_legal_links=Ved at fortsætte godkender du vores {terms} og {privacy}.
firstrun_extra_legal_links=Ved at fortsætte accepterer du vores {terms} og vores {privacy}.
firstrun_terms_of_service=tjenestevilkår
firstrun_privacy_notice=privatlivspolitik
@ -227,3 +227,4 @@ firstrun_skip_login=Spring dette trin over
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Åbn menu
section_menu_action_add_search_engine=Tilføj søgetjeneste

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

@ -208,3 +208,4 @@ firstrun_skip_login=Diesen Schritt überspringen
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Menü öffnen
section_menu_action_add_search_engine=Suchmaschine hinzufügen

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

@ -213,3 +213,4 @@ firstrun_skip_login=Toś ten kšac pśeskócyś
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Meni wócyniś
section_menu_action_add_search_engine=Pytnicu pśidaś

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

@ -212,3 +212,4 @@ firstrun_skip_login=Παράλειψη βήματος
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Άνοιγμα μενού
section_menu_action_add_search_engine=Προσθήκη μηχανής αναζήτησης

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

@ -213,3 +213,4 @@ firstrun_skip_login=Skip this step
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Open menu
section_menu_action_add_search_engine=Add Search Engine

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

@ -208,3 +208,4 @@ firstrun_skip_login=Skip this step
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Open menu
section_menu_action_add_search_engine=Add Search Engine

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

@ -213,3 +213,4 @@ firstrun_skip_login=Pretersalti tiun ĉi paŝon
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Malfermi menuon
section_menu_action_add_search_engine=Aldoni serĉilon

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

@ -206,10 +206,11 @@ firstrun_invalid_input=Se requiere un correo electrónico válido
# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
firstrun_extra_legal_links=Al proceder, acepta los {terms} y {privacy}.
firstrun_terms_of_service=Términos del servicio
firstrun_privacy_notice=Anuncio de privacidad
firstrun_privacy_notice=Nota de privacidad
firstrun_continue_to_login=Continuar
firstrun_skip_login=Saltear este paso
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Abrir menú
section_menu_action_add_search_engine=Agregar buscador

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

@ -211,3 +211,4 @@ firstrun_skip_login=Saltar este paso
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Abrir menú
section_menu_action_add_search_engine=Añadir motor de búsqueda

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

@ -93,6 +93,7 @@ prefs_home_header=Contenido de la página de inicio de Firefox
prefs_home_description=Seleccione el contenido que desea en la pantalla de inicio de Firefox.
prefs_content_discovery_header=Página de inicio de Firefox
prefs_content_discovery_description=Content Discovery en la página de inicio de Firefox le permite descubrir artículos de alta calidad y relevantes de toda la web.
prefs_content_discovery_button=Desactivar Content Discovery
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
@ -212,3 +213,4 @@ firstrun_skip_login=Saltar este paso
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Abrir menú
section_menu_action_add_search_engine=Añadir motor de búsqueda

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

@ -209,3 +209,4 @@ firstrun_skip_login=Saltar este paso
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Abrir menú
section_menu_action_add_search_engine=Agregar motor de búsqueda

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

@ -209,3 +209,4 @@ firstrun_skip_login=Jäta see samm vahele
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Ava menüü
section_menu_action_add_search_engine=Lisa otsingumootor

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

@ -213,3 +213,4 @@ firstrun_skip_login=Saltatu urrats hau
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Ireki menua
section_menu_action_add_search_engine=Gehitu bilaketa-motorra

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

@ -206,3 +206,4 @@ firstrun_skip_login=پرش از این مرحله
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=باز کردن منو
section_menu_action_add_search_engine=افزودن موتور جست‌وجو

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

@ -209,3 +209,4 @@ firstrun_skip_login=Diw ngal daawal
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Uddit cuɓirgol
section_menu_action_add_search_engine=Ɓeydu Masiŋ Njiilaw

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

@ -209,3 +209,4 @@ firstrun_skip_login=Ohita tämä vaihe
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Avaa valikko
section_menu_action_add_search_engine=Lisää hakukone

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

@ -148,7 +148,7 @@ pocket_read_more=Sujets populaires :
# end of the list of popular topic links.
pocket_read_even_more=Afficher plus darticles
pocket_more_reccommendations=Plus de recommandations
pocket_how_it_works=Mode d'emploi
pocket_how_it_works=Mode demploi
pocket_cta_button=Installer Pocket
pocket_cta_text=Enregistrez les articles que vous aimez dans Pocket, et stimulez votre imagination avec des lectures fascinantes.
@ -212,3 +212,4 @@ firstrun_skip_login=Ignorer cette étape
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Ouvrir le menu
section_menu_action_add_search_engine=Ajouter ce moteur de recherche

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

@ -91,6 +91,11 @@ section_disclaimer_topstories_buttontext=Oké, begrepen
# what is shown for the homepage, new windows, and new tabs.
prefs_home_header=Ynhâld fan Firefox-startside
prefs_home_description=Kies hokker ynhâld jo op jo Firefox-startside werjaan wolle.
prefs_content_discovery_header=Firefox Home
prefs_content_discovery_description=Fia Content Discovery op de Firefox-startside kinne jo relevante artikelen op it hiele web mei hege kwaliteit fine.
prefs_content_discovery_button=Content Discovery útskeakelje
# 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 +149,6 @@ pocket_read_more=Populêre ûnderwerpen:
# end of the list of popular topic links.
pocket_read_even_more=Mear ferhalen besjen
pocket_more_reccommendations=Mear oanrekommandaasjes
pocket_learn_more=Mear ynfo
pocket_how_it_works=Hoe it wurket
pocket_cta_button=Pocket brûke
pocket_cta_text=Bewarje de ferhalen dy't jo ynteressant fine yn Pocket, en stimulearje jo tinzen mei boeiende lêsstof.
@ -209,3 +213,4 @@ firstrun_skip_login=Dizze stap oerslaan
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Menu iepenje
section_menu_action_add_search_engine=Sykmasine tafoegje

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

@ -209,3 +209,4 @@ firstrun_skip_login=Leum seachad air seo
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Fosgail an clàr-taice
section_menu_action_add_search_engine=Cuir einnsean-luirg ris

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

@ -209,3 +209,4 @@ firstrun_skip_login=Ignorar este paso
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Abrir menú
section_menu_action_add_search_engine=Engadir buscador

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

@ -211,3 +211,4 @@ firstrun_skip_login=Ehejánte kóva
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Eike poravorãme
section_menu_action_add_search_engine=Embojuaju jehekaha mongueha

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

@ -209,3 +209,4 @@ firstrun_skip_login=આ પગલું છોડી દો
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=મેનૂ ખોલો
section_menu_action_add_search_engine=શોધ યંત્ર ઉમેરો

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

@ -212,3 +212,4 @@ firstrun_skip_login=דילוג על שלב זה
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=פתיחת תפריט
section_menu_action_add_search_engine=הוספת מנוע חיפוש

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

@ -210,3 +210,4 @@ firstrun_skip_login=इस चरण को छोड़ दें
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=मेन्यू खोलें
section_menu_action_add_search_engine=सर्च इंजन जोड़े

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

@ -91,6 +91,11 @@ section_disclaimer_topstories_buttontext=U redu, razumijem
# what is shown for the homepage, new windows, and new tabs.
prefs_home_header=Firefox početni sadržaj
prefs_home_description=Odaberite koji sadržaj želite na vašoj Firefox početnoj stranici.
prefs_content_discovery_header=Firefox početna stranica
prefs_content_discovery_description=Otkrivanje sadržaja u Firefox početnoj stranici pomaže vam u otkrivanju visoko kvalitenih, relevantnih članaka diljem interneta.
prefs_content_discovery_button=Uključite otkrivanje sadržaja
# 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
@ -208,3 +213,4 @@ firstrun_skip_login=Preskočite ovaj korak
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Otvori izbornik
section_menu_action_add_search_engine=Dodaj tražilicu

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

@ -213,3 +213,4 @@ firstrun_skip_login=Tutón krok přeskočić
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Meni wočinić
section_menu_action_add_search_engine=Pytawu přidać

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

@ -213,3 +213,4 @@ firstrun_skip_login=Lépés kihagyása
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Menü megnyitása
section_menu_action_add_search_engine=Keresőszolgáltatás hozzáadása

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

@ -213,3 +213,4 @@ firstrun_skip_login=Saltar iste grado
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Aperir le menu
section_menu_action_add_search_engine=Adder un motor de recerca

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

@ -209,3 +209,4 @@ firstrun_skip_login=Lewati langkah ini
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Buka menu
section_menu_action_add_search_engine=Tambahkan Mesin Pencari

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

@ -91,6 +91,10 @@ section_disclaimer_topstories_buttontext=Allt í lagi, ég skil
# what is shown for the homepage, new windows, and new tabs.
prefs_home_header=Upphafssíða Firefox
prefs_home_description=Veldu hvaða efni þú vilt á Firefox heimaskjánum þínum.
prefs_content_discovery_header=Upphafssíða Firefox
prefs_content_discovery_button=Slökkva á efnisveitu
# 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
@ -208,3 +212,4 @@ firstrun_skip_login=Sleppa þessu skrefi
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Opna valmynd
section_menu_action_add_search_engine=Bæta við leitarvél

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

@ -113,3 +113,4 @@ firstrun_privacy_notice=informativa sulla privacy
firstrun_continue_to_login=Continua
firstrun_skip_login=Ignora questo passaggio
context_menu_title=Apri menu
section_menu_action_add_search_engine=Aggiungi motore di ricerca

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

@ -208,3 +208,4 @@ firstrun_skip_login=この手順をスキップ
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=メニューを開きます
section_menu_action_add_search_engine=検索エンジンを追加

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

@ -208,3 +208,4 @@ firstrun_skip_login=この手順をスキップ
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=メニューを開きます
section_menu_action_add_search_engine=検索エンジンを追加

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

@ -209,3 +209,4 @@ firstrun_skip_login=გამოტოვება
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=მენიუს გახსნა
section_menu_action_add_search_engine=საძიებო სისტემის დამატება

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

@ -93,6 +93,7 @@ prefs_home_header=Agbur agejdan Firefox
prefs_home_description=Fren agbur i tebɣiḍ deg ugdil agejdan Firefox.
prefs_content_discovery_header=Asebter agejdan Firefox
prefs_content_discovery_button=Sens asnirem n ubur
# 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).
@ -211,3 +212,4 @@ firstrun_skip_login=Zgel amecwaṛ-agi
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Ldi umuɣ
section_menu_action_add_search_engine=Rnu amsedday n unadi

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

@ -209,3 +209,4 @@ firstrun_skip_login=Бұл қадамды аттап кету
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Мәзірді ашу
section_menu_action_add_search_engine=Іздеу жүйесін қосу

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

@ -93,6 +93,8 @@ prefs_home_header=Firefox 홈 콘텐츠
prefs_home_description=Firefox 홈 화면에 나올 콘텐츠를 선택하세요.
prefs_content_discovery_header=Firefox 홈
prefs_content_discovery_description=Firefox 홈의 콘텐츠 탐색 기능을 사용하면 웹에 있는 고품질의 관련 문서를 탐색할 수 있습니다.
prefs_content_discovery_button=콘텐츠 탐색 끄기
# 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).
@ -211,3 +213,4 @@ firstrun_skip_login=단계 건너뛰기
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=메뉴 열기
section_menu_action_add_search_engine=검색 엔진 추가

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

@ -208,3 +208,4 @@ firstrun_privacy_notice=Informativa in sciâ privacy
firstrun_continue_to_login=Continoa
firstrun_skip_login=Sata sto passo
section_menu_action_add_search_engine=Azonzi motô de riçerca

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

@ -207,3 +207,4 @@ firstrun_privacy_notice=ນະໂຍບາຍຄວາມເປັນສ່ວ
firstrun_continue_to_login=ສືບຕໍ່
firstrun_skip_login=ຂ້າມຂັ້ນຕອນນີ້
section_menu_action_add_search_engine=ເພີ່ມເຄື່ອງມືການຊອກຫາ

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

@ -213,3 +213,4 @@ firstrun_skip_login=Praleisti šį žingsnį
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Atverti meniu
section_menu_action_add_search_engine=Pridėti ieškyklę

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

@ -202,3 +202,4 @@ firstrun_privacy_notice=Privatuma pīzeime
firstrun_continue_to_login=Turpynōt
firstrun_skip_login=Izlaist itū sūli
section_menu_action_add_search_engine=Daīvīnōt mekleitōji

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

@ -209,3 +209,4 @@ firstrun_skip_login=Izlaist šo soli
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Atvērt izvēlni
section_menu_action_add_search_engine=Pievienot meklētāju

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

@ -91,6 +91,9 @@ section_disclaimer_topstories_buttontext=ठीक आहे, समजले
# what is shown for the homepage, new windows, and new tabs.
prefs_home_header=फायरफॉक्स होम वरील मजकूर
prefs_home_description=आपल्या फायरफॉक्सचा मुख्यपृष्ठवर आपल्याला कोणती माहिती पाहिजे ते निवडा.
prefs_content_discovery_header=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
@ -143,8 +146,9 @@ pocket_read_more=लोकप्रिय विषय:
# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
# end of the list of popular topic links.
pocket_read_even_more=अधिक कथा पहा
pocket_learn_more=अधिक जाणा
pocket_more_reccommendations=अधिक शिफारसी
pocket_how_it_works=हे कसे कार्य करते
pocket_cta_button=Pocket मिळवा
highlights_empty_state=ब्राउझिंग सुरू करा, आणि आम्ही आपल्याला इथे आपण अलीकडील भेट दिलेले किंवा वाचनखूण लावलेले उत्कृष्ठ लेख, व्हिडिओ, आणि इतर पृष्ठांपैकी काही दाखवू.
# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
@ -193,7 +197,6 @@ firstrun_form_header=ईमेल प्रविष्ट करा
firstrun_form_sub_header=Firefox Sync वर सुरू ठेवण्यासाठी
firstrun_email_input_placeholder=ईमेल
firstrun_invalid_input=वैध ईमेल आवश्यक
# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
@ -204,3 +207,7 @@ firstrun_privacy_notice=गोपनीयता सूचना
firstrun_continue_to_login=पुढे चला
firstrun_skip_login=ही पायरी वगळा
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=मेनु उघडा
section_menu_action_add_search_engine=शोध इंजीन जोडा

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

@ -209,3 +209,4 @@ firstrun_skip_login=Langkau langkah ini
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Buka menu
section_menu_action_add_search_engine=Tambah Enjin Carian

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

@ -209,3 +209,4 @@ firstrun_skip_login=Hopp over dette trinnet
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Åpne meny
section_menu_action_add_search_engine=Legg til søkemotor

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

@ -213,3 +213,4 @@ firstrun_skip_login=Deze stap overslaan
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Menu openen
section_menu_action_add_search_engine=Zoekmachine toevoegen

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

@ -91,6 +91,9 @@ section_disclaimer_topstories_buttontext=OK, eg forstår det!
# what is shown for the homepage, new windows, and new tabs.
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
# 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=Populære emne:
# end of the list of popular topic links.
pocket_read_even_more=Vis fleire saker
pocket_more_reccommendations=Fleire tilrådingar
pocket_learn_more=Les meir
pocket_how_it_works=Korleis det fungerar
pocket_cta_button=Last ned Pocket
pocket_cta_text=Lagre artiklane du synest er interessante i Pocket, og stimuler tankane dine med fasinerande lesemateriell.
@ -209,3 +211,4 @@ firstrun_skip_login=Hopp over dette steget
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Opne meny
section_menu_action_add_search_engine=Legg til søkjemotor

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

@ -207,3 +207,4 @@ firstrun_skip_login=Passar aquesta etapa
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Dobrir lo menú
section_menu_action_add_search_engine=Apondre un motor de recèrca

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

@ -90,6 +90,9 @@ section_disclaimer_topstories_buttontext=ਠੀਕ ਹੈ, ਸਮਝ ਲਿਆ
# what is shown for the homepage, new windows, and new tabs.
prefs_home_header=ਫਾਇਰਫਾਕਸ ਮੁੱਖ ਪੰਨਾ
prefs_home_description=ਉਹ ਸਮੱਗਰੀ ਚੁਣੋ ਜੋ ਤੁਸੀਂ ਆਪਣੇ ਫਾਇਰਫਾਕਸ ਮੁੱਖ ਪੰਨੇ 'ਤੇ ਚਾਹੁੰਦੇ ਹੋ।
prefs_content_discovery_header=ਫਾਇਰਫਾਕਸ ਮੁੱਖ ਸਫ਼ਾ
# 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
@ -97,7 +100,7 @@ prefs_section_rows_option={num} ਕਤਾਰ;{num} ਕਤਾਰਾਂ
prefs_search_header=ਵੈੱਬ ਖੋਜ
prefs_topsites_description=ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਭ ਤੋਂ ਵੱਧ ਵੇਖੀਆਂ ਸਾਈਟਾਂ
prefs_topstories_description2=ਸਮੁੱਚੇ ਵੈੱਬ ਤੋਂ ਸ਼ਾਨਦਾਰ ਸਮੱਗਰੀ, ਤੁਹਾਡੇ ਲਈ ਵਿਅਕਤੀਗਤ ਹੈ
prefs_topstories_options_sponsored_label=ਪ੍ਰਾਯੋਜਿਤ ਕਹਾਣੀਆਂ
prefs_topstories_options_sponsored_label=ਸਪਾਂਸਰ ਕੀਤੀਆਂ ਕਹਾਣੀਆਂ
prefs_topstories_sponsored_learn_more=ਹੋਰ ਜਾਣੋ
prefs_highlights_description=ਉਹਨਾਂ ਸਾਈਟਾਂ ਦੀ ਚੋਣ ਕਰੋ ਜੋ ਤੁਸੀਂ ਸੁਰੱਖਿਅਤ ਜਾਂ ਵਿਜ਼ਿਟ ਕੀਤੀ ਹੈ
prefs_highlights_options_visited_label=ਵੇਖੇ ਗਏ ਸਫੇ
@ -129,7 +132,7 @@ topsites_form_image_url_label=URL ਕਸਟਮ ਚਿੱਤਰ
topsites_form_url_placeholder=ਕੋਈ URL ਲਿਖੋ ਜਾਂ ਚੇਪੋ
topsites_form_use_image_link=ਇੱਕ ਕਸਟਮ ਚਿੱਤਰ ਵਰਤੋ…
# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
topsites_form_preview_button=ਪੂਰਵ ਦਰਸ਼ਨ
topsites_form_preview_button=ਝਲਕ
topsites_form_add_button=ਜੋੜੋ
topsites_form_save_button=ਸੰਭਾਲੋ
topsites_form_cancel_button=ਰੱਦ ਕਰੋ
@ -143,7 +146,6 @@ pocket_read_more=ਪ੍ਰਸਿੱਧ ਵਿਸ਼ੇ:
# end of the list of popular topic links.
pocket_read_even_more=ਹੋਰ ਕਹਾਣੀਆਂ ਵੇਖੋ
pocket_more_reccommendations=ਹੋਰ ਸਿਫਾਰਸ਼ਾਂ
pocket_learn_more=ਹੋਰ ਸਿੱਖੋ
pocket_how_it_works=ਇਹ ਕਿਵੇਂ ਕੰਮ ਕਰਦੀ ਹੈ
pocket_cta_button=ਪਾਕੇਟ ਲਵੋ
@ -170,7 +172,7 @@ error_fallback_default_refresh_suggestion=ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ
section_menu_action_remove_section=ਸੈਕਸ਼ਨ ਹਟਾਓ
section_menu_action_collapse_section=ਸੈਕਸ਼ਨ ਨੂੰ ਸਮੇਟੋ
section_menu_action_expand_section=ਸੈਕਸ਼ਨ ਦੀ ਫੈਲਾਓ
section_menu_action_manage_section=ਸੈਕਸ਼ਨ ਦਾ ਪ੍ਰਬੰਧ ਕਰੋ
section_menu_action_manage_section=ਸੈਕਸ਼ਨ ਦਾ ਬੰਦੋਬਸਤ
section_menu_action_manage_webext=ਇਕਸਟੈਨਸ਼ਨਾਂ ਦਾ ਇੰਤਜ਼ਾਮ
section_menu_action_add_topsite=ਚੋਟੀ ਦੀਆਂ ਸਾਈਟਾਂ ਜੋੜੋ
section_menu_action_add_search_engine=ਖੋਜ ਇੰਜਣ ਜੋੜੋ
@ -204,3 +206,4 @@ firstrun_skip_login=ਇਹ ਪਗ਼ ਛੱਡੋ
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=ਮੇਨੂ ਖੋਲ੍ਹੋ
section_menu_action_add_search_engine=ਖੋਜ ਇੰਜਣ ਜੋੜੋ

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

@ -125,3 +125,4 @@ firstrun_continue_to_login=Kontynuuj
firstrun_skip_login=Pomiń
context_menu_title=Otwórz menu
section_menu_action_add_search_engine=Dodaj wyszukiwarkę

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

@ -100,7 +100,7 @@ prefs_content_discovery_button=Desativar descoberta de conteúdo
# 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
prefs_section_rows_option={num} linha;{num} linhas
prefs_search_header=Pesquisa na web
prefs_search_header=Pesquisar na web
prefs_topsites_description=Os sites que você mais visita
prefs_topstories_description2=Os melhores conteúdos disponíveis na Web, personalizados pra você
prefs_topstories_options_sponsored_label=Histórias patrocinadas
@ -213,3 +213,4 @@ firstrun_skip_login=Pular essa etapa
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Abrir menu
section_menu_action_add_search_engine=Adicionar mecanismo de busca

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

@ -213,3 +213,4 @@ firstrun_skip_login=Saltar este passo
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Abrir menu
section_menu_action_add_search_engine=Adicionar motor de pesquisa

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

@ -213,3 +213,4 @@ firstrun_skip_login=Sursiglir quest pass
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Avrir il menu
section_menu_action_add_search_engine=Agiuntar questa maschina da tschertgar

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

@ -91,6 +91,11 @@ section_disclaimer_topstories_buttontext=Ok, am înțeles
# what is shown for the homepage, new windows, and new tabs.
prefs_home_header=Conținutul paginii de start Firefox
prefs_home_description=Alege ce conținut vrei pe ecranul de start Firefox.
prefs_content_discovery_header=Pagina de start Firefox
prefs_content_discovery_description=Descoperirea de conținut din pagina de start Firefox îți permite să descoperi articole relevante de calitate înaltă de pe web.
prefs_content_discovery_button=Dezactivează descoperirea de conținut
# 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 +149,6 @@ pocket_read_more=Subiecte populare:
# end of the list of popular topic links.
pocket_read_even_more=Vezi mai multe articole
pocket_more_reccommendations=Mai multe recomandări
pocket_learn_more=Află mai multe
pocket_how_it_works=Cum funcționează
pocket_cta_button=Obține Pocket
pocket_cta_text=Salvează în Pocket articolele care ți-au plăcut și hrănește-ți mintea cu lecturi fascinante.
@ -209,3 +213,4 @@ firstrun_skip_login=Omite acest pas
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Deschide meniul
section_menu_action_add_search_engine=Adaugă motor de căutare

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

@ -213,3 +213,4 @@ firstrun_skip_login=Пропустить этот шаг
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Открыть меню
section_menu_action_add_search_engine=Добавить поисковую систему

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

@ -209,3 +209,4 @@ firstrun_skip_login=Preskočiť tento krok
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Otvorí ponuku
section_menu_action_add_search_engine=Pridať vyhľadávací modul

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

@ -213,3 +213,4 @@ firstrun_skip_login=Preskoči ta korak
# LOCALIZATION NOTE (context_menu_title): Action tooltip to open a context menu
context_menu_title=Odpri meni
section_menu_action_add_search_engine=Dodaj iskalnik

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше