mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Merge mozilla-central to inbound. a=merge CLOSED TREE
This commit is contained in:
commit
800cbc5955
@ -6186,7 +6186,7 @@ function middleMousePaste(event) {
|
||||
// bar's behavior (stripsurroundingwhitespace)
|
||||
clipboard = clipboard.replace(/\s*\n\s*/g, "");
|
||||
|
||||
clipboard = stripUnsafeProtocolOnPaste(clipboard);
|
||||
clipboard = UrlbarUtils.stripUnsafeProtocolOnPaste(clipboard);
|
||||
|
||||
// if it's not the current tab, we don't need to do anything because the
|
||||
// browser doesn't exist.
|
||||
@ -6227,23 +6227,6 @@ function middleMousePaste(event) {
|
||||
}
|
||||
}
|
||||
|
||||
function stripUnsafeProtocolOnPaste(pasteData) {
|
||||
// Don't allow pasting javascript URIs since we don't support
|
||||
// LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL for those.
|
||||
while (true) {
|
||||
let scheme = "";
|
||||
try {
|
||||
scheme = Services.io.extractScheme(pasteData);
|
||||
} catch (ex) { }
|
||||
if (scheme != "javascript") {
|
||||
break;
|
||||
}
|
||||
|
||||
pasteData = pasteData.substring(pasteData.indexOf(":") + 1);
|
||||
}
|
||||
return pasteData;
|
||||
}
|
||||
|
||||
// handleDroppedLink has the following 2 overloads:
|
||||
// handleDroppedLink(event, url, name, triggeringPrincipal)
|
||||
// handleDroppedLink(event, links, triggeringPrincipal)
|
||||
|
@ -32,7 +32,7 @@ skip-if = (os == 'win' && bits == 32) # Bug 1488537
|
||||
skip-if = (verify && (os == 'mac'))
|
||||
[browser_tabopen_squeeze.js]
|
||||
[browser_tabstrip_overflow_underflow.js]
|
||||
skip-if = (verify && !debug && (os == 'win'))
|
||||
skip-if = (verify && !debug && (os == 'win')) || (!debug && (os == 'win') && (bits == 32)) # Bug 1502255
|
||||
[browser_tabswitch.js]
|
||||
[browser_toolbariconcolor_restyles.js]
|
||||
[browser_urlbar_keyed_search.js]
|
||||
|
@ -1000,7 +1000,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
let triggeringPrincipal = browserDragAndDrop.getTriggeringPrincipal(aEvent);
|
||||
aEvent.preventDefault();
|
||||
let url = links[0].url;
|
||||
let strippedURL = stripUnsafeProtocolOnPaste(url);
|
||||
let strippedURL = UrlbarUtils.stripUnsafeProtocolOnPaste(url);
|
||||
if (strippedURL != url) {
|
||||
aEvent.stopImmediatePropagation();
|
||||
return null;
|
||||
@ -1275,7 +1275,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
}
|
||||
let oldEnd = oldValue.substring(this.inputField.selectionEnd);
|
||||
|
||||
let pasteData = stripUnsafeProtocolOnPaste(originalPasteData);
|
||||
let pasteData = UrlbarUtils.stripUnsafeProtocolOnPaste(originalPasteData);
|
||||
if (originalPasteData != pasteData) {
|
||||
// Unfortunately we're not allowed to set the bits being pasted
|
||||
// so cancel this event:
|
||||
|
@ -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;
|
||||
|
File diff suppressed because one or more lines are too long
@ -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;
|
||||
|
File diff suppressed because one or more lines are too long
@ -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;
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -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 d’articles
|
||||
pocket_more_reccommendations=Plus de recommandations
|
||||
pocket_how_it_works=Mode d'emploi
|
||||
pocket_how_it_works=Mode d’emploi
|
||||
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 mongu’eha
|
||||
|
@ -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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user