Bug 1476079 - Add onboarding focus, funneling metrics and bug fixes to Activity Stream. r=ursula

MozReview-Commit-ID: 66sjBl8LBQu

--HG--
extra : rebase_source : c6b3ecf1e011e2a98aa3c4612b19c90868bbefb0
This commit is contained in:
Ed Lee 2018-07-16 13:38:58 -07:00
Родитель 826bfa5d74
Коммит 2d63e9e89f
44 изменённых файлов: 508 добавлений и 421 удалений

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

@ -0,0 +1,111 @@
exports.DEFAULT_LOCALE = "en-US";
// This locales list is to find any similar locales that we can reuse strings
// instead of falling back to the default, e.g., use bn-BD strings for bn-IN.
// https://hg.mozilla.org/mozilla-central/file/tip/browser/locales/l10n.toml
exports.CENTRAL_LOCALES = [
"ach",
"af",
"an",
"ar",
"as",
"ast",
"az",
"be",
"bg",
"bn-BD",
"bn-IN",
"br",
"bs",
"ca",
"cak",
"crh",
"cs",
"cy",
"da",
"de",
"dsb",
"el",
"en-CA",
"en-GB",
"en-ZA",
"eo",
"es-AR",
"es-CL",
"es-ES",
"es-MX",
"et",
"eu",
"fa",
"ff",
"fi",
"fr",
"fy-NL",
"ga-IE",
"gd",
"gl",
"gn",
"gu-IN",
"he",
"hi-IN",
"hr",
"hsb",
"hu",
"hy-AM",
"ia",
"id",
"is",
"it",
"ja",
"ja-JP-mac",
"ka",
"kab",
"kk",
"km",
"kn",
"ko",
"lij",
"lo",
"lt",
"ltg",
"lv",
"mai",
"mk",
"ml",
"mr",
"ms",
"my",
"nb-NO",
"ne-NP",
"nl",
"nn-NO",
"oc",
"or",
"pa-IN",
"pl",
"pt-BR",
"pt-PT",
"rm",
"ro",
"ru",
"si",
"sk",
"sl",
"son",
"sq",
"sr",
"sv-SE",
"ta",
"te",
"th",
"tl",
"tr",
"uk",
"ur",
"uz",
"vi",
"wo",
"xh",
"zh-CN",
"zh-TW"
];

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

@ -6,7 +6,7 @@ const path = require("path");
// Note: this file is generated by webpack from content-src/activity-stream-prerender.jsx
const {prerender} = require("./prerender");
const DEFAULT_LOCALE = "en-US";
const {CENTRAL_LOCALES, DEFAULT_LOCALE} = require("./locales");
// Note: DEFAULT_OPTIONS.baseUrl should match BASE_URL in aboutNewTabService.js
// in mozilla-central.
@ -15,116 +15,6 @@ const DEFAULT_OPTIONS = {
baseUrl: "resource://activity-stream/"
};
// This locales list is to find any similar locales that we can reuse strings
// instead of falling back to the default, e.g., use bn-BD strings for bn-IN.
// https://hg.mozilla.org/mozilla-central/file/tip/browser/locales/l10n.toml
const CENTRAL_LOCALES = [
"ach",
"af",
"an",
"ar",
"as",
"ast",
"az",
"be",
"bg",
"bn-BD",
"bn-IN",
"br",
"bs",
"ca",
"cak",
"crh",
"cs",
"cy",
"da",
"de",
"dsb",
"el",
"en-CA",
"en-GB",
"en-ZA",
"eo",
"es-AR",
"es-CL",
"es-ES",
"es-MX",
"et",
"eu",
"fa",
"ff",
"fi",
"fr",
"fy-NL",
"ga-IE",
"gd",
"gl",
"gn",
"gu-IN",
"he",
"hi-IN",
"hr",
"hsb",
"hu",
"hy-AM",
"ia",
"id",
"is",
"it",
"ja",
"ja-JP-mac",
"ka",
"kab",
"kk",
"km",
"kn",
"ko",
"lij",
"lo",
"lt",
"ltg",
"lv",
"mai",
"mk",
"ml",
"mr",
"ms",
"my",
"nb-NO",
"ne-NP",
"nl",
"nn-NO",
"oc",
"or",
"pa-IN",
"pl",
"pt-BR",
"pt-PT",
"rm",
"ro",
"ru",
"si",
"sk",
"sl",
"son",
"sq",
"sr",
"sv-SE",
"ta",
"te",
"th",
"tl",
"tr",
"uk",
"ur",
"uz",
"vi",
"wo",
"xh",
"zh-CN",
"zh-TW"
];
// Locales that should be displayed RTL
const RTL_LIST = ["ar", "he", "fa", "ur"];

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

@ -7,7 +7,7 @@ const fetch = require("node-fetch");
/* globals cd, ls, mkdir, rm, ShellString */
require("shelljs/global");
const DEFAULT_LOCALE = "en-US";
const {CENTRAL_LOCALES, DEFAULT_LOCALE} = require("./locales");
const L10N_CENTRAL = "https://hg.mozilla.org/l10n-central";
const PROPERTIES_PATH = "raw-file/default/browser/chrome/browser/activity-stream/newtab.properties";
const STRINGS_FILE = "strings.properties";
@ -16,16 +16,21 @@ const STRINGS_FILE = "strings.properties";
async function getLocales() {
console.log(`Getting locales from ${L10N_CENTRAL}`);
// Add all non-test sub repository locales
// Add sub repository locales that mozilla-central builds
const locales = [];
const unbuilt = [];
const subrepos = await (await fetch(`${L10N_CENTRAL}?style=json`)).json();
subrepos.entries.forEach(({name}) => {
if (name !== "x-testing") {
if (CENTRAL_LOCALES.includes(name)) {
locales.push(name);
} else {
unbuilt.push(name);
}
});
console.log(`Got ${locales.length} locales: ${locales}`);
console.log(`Got ${locales.length} mozilla-central locales: ${locales}`);
console.log(`Skipped ${unbuilt.length} unbuilt locales: ${unbuilt}`);
return locales;
}
@ -62,9 +67,17 @@ async function updateLocales() {
}
});
// Save the properties file for each locale in parallel
const locales = await getLocales();
const missing = (await Promise.all(locales.map(saveProperties))).filter(v => v);
// Save the properties file for each locale one at a time to avoid too many
// parallel connections (resulting in ECONNRESET / socket hang up)
const missing = [];
for (const locale of await getLocales()) {
process.stdout.write(`${locale} `);
if (await saveProperties(locale)) {
missing.push(locale);
}
}
console.log("");
console.log(`Skipped ${missing.length} locales without strings: ${missing.sort()}`);
console.log(`

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

@ -21,7 +21,7 @@ export class ModalOverlay extends React.PureComponent {
<h2> {title} </h2>
{this.props.children}
<div className="footer">
<button onClick={this.props.onDoneButton} className="button primary modalButton"> {button_label} </button>
<button tabIndex="2" onClick={this.props.onDoneButton} className="button primary modalButton"> {button_label} </button>
</div>
</div>
</div>

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

@ -99,6 +99,12 @@
height: 30px;
padding: 4px 0 6px;
font-size: 15px;
&:focus,
&.active {
box-shadow: $shadow-primary;
transition: box-shadow 150ms;
}
}
}
}

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

@ -8,7 +8,7 @@ Field name | Type | Required | Description | Example / Note
`publish_end` | `date` | No | When to stop showing the message | `1524474850876`
`content` | `object` | Yes | An object containing all variables/props to be rendered in the template. Subset of allowed tags detailed below. | [See example below](#html-subset)
`campaign` | `string` | No | Campaign id that the message belongs to | `RustWebAssembly`
`targeting` | `string` `JEXL` | No | A [JEXL expression](http://normandy.readthedocs.io/en/latest/user/filter_expressions.html#jexl-basics) with all targeting information needed in order to decide if the message is shown | Not yet implemented, [some examples](http://normandy.readthedocs.io/en/latest/user/filter_expressions.html#examples)
`targeting` | `string` `JEXL` | No | A [JEXL expression](http://normandy.readthedocs.io/en/latest/user/filter_expressions.html#jexl-basics) with all targeting information needed in order to decide if the message is shown | Not yet implemented, [Examples](#targeting-attributes)
`trigger` | `string` | No | An event or condition upon which the message will be immediately shown. This can be combined with `targeting`. Messages that define a trigger will not be shown during non-trigger-based passive message rotation.
### Message example
@ -43,3 +43,62 @@ Links cannot be rendered using regular anchor tags because [Fluent does not allo
If a tag that is not on the allowed is used, the text content will be extracted and displayed.
Grouping multiple allowed elements is not possible, only the first level will be used: `<u><b>text</b></u>` will be interpreted as `<u>text</u>`.
### Targeting attributes
For a more in-depth explanation of JEXL syntax you can read the [Normady project docs](https://normandy.readthedocs.io/en/stable/user/filters.html#jexl-basics).
Currently we expose the following targeting attributes that can be used by messages:
Name | Type | Example value | Description
--- | --- | --- | ---
`profileAgeCreated` | Number | `1522843725924` | Profile creation timestamp
`profileAgeReset` | `Number` or `undefined` | `1522843725924` | When (if) the profile was reset
`hasFxAccount` | `Boolean` | `true` | Does the user have a firefox account
`addonsInfo` | `Object` | [example below](#addonsinfo-example) | Information about the addons the user has installed
#### addonsInfo Example
```javascript
{
"addons": {
...
"activity-stream@mozilla.org": {
"version": "2018.07.06.1113-783442c0",
"type": "extension",
"isSystem": true,
"isWebExtension": false,
"name": "Activity Stream",
"userDisabled": false,
"installDate": "2018-03-10T03:41:06.000Z"
}
},
"isFullData": true
}
```
#### Usage
A message needs to contain the `targeting` property (JEXL string) which is evaluated against the provided attributes.
Examples:
```javascript
{
"id": "7864",
"content": {...},
// simple equality check
"targeting": "hasFxAccount == true"
}
{
"id": "7865",
"content": {...},
// using JEXL transforms and combining two attributes
"targeting": "hasFxAccount == true && profileAgeCreated > '2018-01-07'|date"
}
{
"id": "7866",
"content": {...},
// targeting addon information
"targeting": "addonsInfo.addons['activity-stream@mozilla.org'].name == 'Activity Stream'"
}
```

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

@ -24,7 +24,7 @@ class OnboardingCard extends React.PureComponent {
<p> {content.text} </p>
</span>
<span>
<button className="button onboardingButton" onClick={this.onClick}> {content.button_label} </button>
<button tabIndex="1" className="button onboardingButton" onClick={this.onClick}> {content.button_label} </button>
</span>
</div>
</div>

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

@ -131,6 +131,12 @@
float: none;
margin-top: 30px;
}
&:focus,
&.active {
box-shadow: $shadow-primary;
transition: box-shadow 150ms;
}
}

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

@ -1,5 +1,5 @@
import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
import {FormattedMessage, injectIntl} from "react-intl";
import {actionCreators as ac} from "common/Actions.jsm";
import {connect} from "react-redux";
import React from "react";
@ -15,8 +15,29 @@ export class _StartupOverlay extends React.PureComponent {
this.state = {
emailInput: "",
overlayRemoved: false
overlayRemoved: false,
flowId: "",
flowBeginTime: 0
};
this.didFetch = false;
}
async componentWillUpdate() {
if (this.props.fxa_endpoint && !this.didFetch) {
try {
this.didFetch = true;
const response = await fetch(`${this.props.fxa_endpoint}/metrics-flow`);
if (response.status === 200) {
const {flowId, flowBeginTime} = await response.json();
this.setState({flowId, flowBeginTime});
}
} catch (error) {
this.props.dispatch(ac.OnlyToMain({type: at.TELEMETRY_UNDESIRED_EVENT, data: {value: "FXA_METRICS_ERROR"}}));
}
}
}
componentDidMount() {
this.initScene();
}
@ -71,8 +92,9 @@ export class _StartupOverlay extends React.PureComponent {
return null;
}
let termsLink = (<a href="https://accounts.firefox.com/legal/terms" target="_blank" rel="noopener noreferrer"><FormattedMessage id="firstrun_terms_of_service" /></a>);
let privacyLink = (<a href="https://accounts.firefox.com/legal/privacy" target="_blank" rel="noopener noreferrer"><FormattedMessage id="firstrun_privacy_notice" /></a>);
let termsLink = (<a href={`${this.props.fxa_endpoint}/legal/terms`} target="_blank" rel="noopener noreferrer"><FormattedMessage id="firstrun_terms_of_service" /></a>);
let privacyLink = (<a href={`${this.props.fxa_endpoint}/legal/privacy`} target="_blank" rel="noopener noreferrer"><FormattedMessage id="firstrun_privacy_notice" /></a>);
return (
<div className={`overlay-wrapper ${this.state.show ? "show" : ""}`}>
<div className="background" />
@ -85,13 +107,15 @@ export class _StartupOverlay extends React.PureComponent {
</div>
<div className="firstrun-sign-in">
<p className="form-header"><FormattedMessage id="firstrun_form_header" /><span className="sub-header"><FormattedMessage id="firstrun_form_sub_header" /></span></p>
<form method="get" action="https://accounts.firefox.com" target="_blank" rel="noopener noreferrer" onSubmit={this.onSubmit}>
<form method="get" action={this.props.fxa_endpoint} target="_blank" rel="noopener noreferrer" onSubmit={this.onSubmit}>
<input name="service" type="hidden" value="sync" />
<input name="action" type="hidden" value="email" />
<input name="context" type="hidden" value="fx_desktop_v3" />
<input name="entrypoint" type="hidden" value="activity-stream-firstrun" />
<input name="utm_source" type="hidden" value="activity-stream" />
<input name="utm_campaign" type="hidden" value="firstrun" />
<input name="flow_id" type="hidden" value={this.state.flowId} />
<input name="flow_begin_time" type="hidden" value={this.state.flowBeginTime} />
<span className="error">{this.props.intl.formatMessage({id: "firstrun_invalid_input"})}</span>
<input className="email-input" name="email" type="email" required="true" onInvalid={this.onInputInvalid} placeholder={this.props.intl.formatMessage({id: "firstrun_email_input_placeholder"})} onChange={this.onInputChange} />
<div className="extra-links">
@ -113,4 +137,5 @@ export class _StartupOverlay extends React.PureComponent {
}
}
export const StartupOverlay = connect()(injectIntl(_StartupOverlay));
const getState = state => ({fxa_endpoint: state.Prefs.values.fxa_endpoint});
export const StartupOverlay = connect(getState)(injectIntl(_StartupOverlay));

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

@ -18,7 +18,8 @@ body {
font-size: 16px;
overflow-y: scroll;
&.hide-onboarding, &.hide-main > #onboarding-overlay-button {
&.hide-onboarding > #onboarding-overlay-button,
&.hide-main > #onboarding-overlay-button {
display: none !important;
}

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

@ -230,7 +230,8 @@ body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Helvetica Neue', sans-serif;
font-size: 16px;
overflow-y: scroll; }
body.hide-onboarding, body.hide-main > #onboarding-overlay-button {
body.hide-onboarding > #onboarding-overlay-button,
body.hide-main > #onboarding-overlay-button {
display: none !important; }
body.hide-main > #onboarding-notification-bar {
display: none; }
@ -1844,6 +1845,9 @@ a.firstrun-link {
height: 30px;
padding: 4px 0 6px;
font-size: 15px; }
.modalOverlayInner .footer .modalButton:focus, .modalOverlayInner .footer .modalButton.active {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
transition: box-shadow 150ms; }
.SimpleSnippet.tall {
padding: 27px 0; }
@ -1976,6 +1980,9 @@ a.firstrun-link {
.onboardingMessage .onboardingButton {
float: none;
margin-top: 30px; } }
.onboardingMessage .onboardingButton:focus, .onboardingMessage .onboardingButton.active {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
transition: box-shadow 150ms; }
.onboardingMessage::before {
content: '';
height: 220px;

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

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

@ -233,7 +233,8 @@ body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Helvetica Neue', sans-serif;
font-size: 16px;
overflow-y: scroll; }
body.hide-onboarding, body.hide-main > #onboarding-overlay-button {
body.hide-onboarding > #onboarding-overlay-button,
body.hide-main > #onboarding-overlay-button {
display: none !important; }
body.hide-main > #onboarding-notification-bar {
display: none; }
@ -1847,6 +1848,9 @@ a.firstrun-link {
height: 30px;
padding: 4px 0 6px;
font-size: 15px; }
.modalOverlayInner .footer .modalButton:focus, .modalOverlayInner .footer .modalButton.active {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
transition: box-shadow 150ms; }
.SimpleSnippet.tall {
padding: 27px 0; }
@ -1979,6 +1983,9 @@ a.firstrun-link {
.onboardingMessage .onboardingButton {
float: none;
margin-top: 30px; } }
.onboardingMessage .onboardingButton:focus, .onboardingMessage .onboardingButton.active {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
transition: box-shadow 150ms; }
.onboardingMessage::before {
content: '';
height: 220px;

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

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

@ -230,7 +230,8 @@ body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Helvetica Neue', sans-serif;
font-size: 16px;
overflow-y: scroll; }
body.hide-onboarding, body.hide-main > #onboarding-overlay-button {
body.hide-onboarding > #onboarding-overlay-button,
body.hide-main > #onboarding-overlay-button {
display: none !important; }
body.hide-main > #onboarding-notification-bar {
display: none; }
@ -1844,6 +1845,9 @@ a.firstrun-link {
height: 30px;
padding: 4px 0 6px;
font-size: 15px; }
.modalOverlayInner .footer .modalButton:focus, .modalOverlayInner .footer .modalButton.active {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
transition: box-shadow 150ms; }
.SimpleSnippet.tall {
padding: 27px 0; }
@ -1976,6 +1980,9 @@ a.firstrun-link {
.onboardingMessage .onboardingButton {
float: none;
margin-top: 30px; } }
.onboardingMessage .onboardingButton:focus, .onboardingMessage .onboardingButton.active {
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
transition: box-shadow 150ms; }
.onboardingMessage::before {
content: '';
height: 220px;

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

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

@ -4605,13 +4605,15 @@ const TopSiteList = Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["injectIntl"]
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_StartupOverlay", function() { return _StartupOverlay; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StartupOverlay", function() { return StartupOverlay; });
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13);
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
/* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(13);
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16);
/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_3__);
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
@ -4629,8 +4631,33 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
this.state = {
emailInput: "",
overlayRemoved: false
overlayRemoved: false,
flowId: "",
flowBeginTime: 0
};
this.didFetch = false;
}
componentWillUpdate() {
var _this = this;
return _asyncToGenerator(function* () {
if (_this.props.fxa_endpoint && !_this.didFetch) {
try {
_this.didFetch = true;
const response = yield fetch(`${_this.props.fxa_endpoint}/metrics-flow`);
if (response.status === 200) {
const { flowId, flowBeginTime } = yield response.json();
_this.setState({ flowId, flowBeginTime });
}
} catch (error) {
_this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].OnlyToMain({ type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].TELEMETRY_UNDESIRED_EVENT, data: { value: "FXA_METRICS_ERROR" } }));
}
}
})();
}
componentDidMount() {
this.initScene();
}
@ -4661,12 +4688,12 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
}
onSubmit() {
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_1__["actionCreators"].UserEvent({ event: "SUBMIT_EMAIL" }));
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].UserEvent({ event: "SUBMIT_EMAIL" }));
window.addEventListener("visibilitychange", this.removeOverlay);
}
clickSkip() {
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_1__["actionCreators"].UserEvent({ event: "SKIPPED_SIGNIN" }));
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].UserEvent({ event: "SKIPPED_SIGNIN" }));
this.removeOverlay();
}
@ -4687,14 +4714,15 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
let termsLink = react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"a",
{ href: "https://accounts.firefox.com/legal/terms", target: "_blank", rel: "noopener noreferrer" },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_terms_of_service" })
{ href: `${this.props.fxa_endpoint}/legal/terms`, target: "_blank", rel: "noopener noreferrer" },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_terms_of_service" })
);
let privacyLink = react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"a",
{ href: "https://accounts.firefox.com/legal/privacy", target: "_blank", rel: "noopener noreferrer" },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_privacy_notice" })
{ href: `${this.props.fxa_endpoint}/legal/privacy`, target: "_blank", rel: "noopener noreferrer" },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_privacy_notice" })
);
return react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"div",
{ className: `overlay-wrapper ${this.state.show ? "show" : ""}` },
@ -4711,17 +4739,17 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"h1",
{ className: "firstrun-title" },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_title" })
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_title" })
),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"p",
{ className: "firstrun-content" },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_content" })
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_content" })
),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"a",
{ className: "firstrun-link", href: "https://www.mozilla.org/firefox/features/sync/", target: "_blank", rel: "noopener noreferrer" },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_learn_more_link" })
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_learn_more_link" })
)
),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
@ -4730,22 +4758,24 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"p",
{ className: "form-header" },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_form_header" }),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_form_header" }),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"span",
{ className: "sub-header" },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_form_sub_header" })
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_form_sub_header" })
)
),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"form",
{ method: "get", action: "https://accounts.firefox.com", target: "_blank", rel: "noopener noreferrer", onSubmit: this.onSubmit },
{ method: "get", action: this.props.fxa_endpoint, target: "_blank", rel: "noopener noreferrer", onSubmit: this.onSubmit },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "service", type: "hidden", value: "sync" }),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "action", type: "hidden", value: "email" }),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "context", type: "hidden", value: "fx_desktop_v3" }),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "entrypoint", type: "hidden", value: "activity-stream-firstrun" }),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "utm_source", type: "hidden", value: "activity-stream" }),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "utm_campaign", type: "hidden", value: "firstrun" }),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "flow_id", type: "hidden", value: this.state.flowId }),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "flow_begin_time", type: "hidden", value: this.state.flowBeginTime }),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"span",
{ className: "error" },
@ -4755,7 +4785,7 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"div",
{ className: "extra-links" },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], {
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], {
id: "firstrun_extra_legal_links",
values: {
terms: termsLink,
@ -4765,13 +4795,13 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"button",
{ className: "continue-button", type: "submit" },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_continue_to_login" })
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_continue_to_login" })
)
),
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
"button",
{ className: "skip-button", disabled: !!this.state.emailInput, onClick: this.clickSkip },
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_skip_login" })
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_skip_login" })
)
)
)
@ -4780,7 +4810,8 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
}
}
const StartupOverlay = Object(react_redux__WEBPACK_IMPORTED_MODULE_2__["connect"])()(Object(react_intl__WEBPACK_IMPORTED_MODULE_0__["injectIntl"])(_StartupOverlay));
const getState = state => ({ fxa_endpoint: state.Prefs.values.fxa_endpoint });
const StartupOverlay = Object(react_redux__WEBPACK_IMPORTED_MODULE_2__["connect"])(getState)(Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["injectIntl"])(_StartupOverlay));
/***/ }),
/* 37 */
@ -8100,7 +8131,7 @@ class ModalOverlay_ModalOverlay extends external_React_default.a.PureComponent {
{ className: "footer" },
external_React_default.a.createElement(
"button",
{ onClick: this.props.onDoneButton, className: "button primary modalButton" },
{ tabIndex: "2", onClick: this.props.onDoneButton, className: "button primary modalButton" },
" ",
button_label,
" "
@ -8161,7 +8192,7 @@ class OnboardingMessage_OnboardingCard extends external_React_default.a.PureComp
null,
external_React_default.a.createElement(
"button",
{ className: "button onboardingButton", onClick: this.onClick },
{ tabIndex: "1", className: "button onboardingButton", onClick: this.onClick },
" ",
content.button_label,
" "

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

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

@ -8,7 +8,7 @@
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:unpack>false</em:unpack>
<em:version>2018.07.12.1202-ecc4456e</em:version>
<em:version>2018.07.16.1239-6f362fbc</em:version>
<em:name>Activity Stream</em:name>
<em:description>A rich visual history feed and a reimagined home page make it easier than ever to find exactly what you're looking for in Firefox.</em:description>
<em:multiprocessCompatible>true</em:multiprocessCompatible>

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

@ -16,9 +16,6 @@ const INCOMING_MESSAGE_NAME = "ASRouter:child-to-parent";
const OUTGOING_MESSAGE_NAME = "ASRouter:parent-to-child";
const ONE_HOUR_IN_MS = 60 * 60 * 1000;
const SNIPPETS_ENDPOINT_PREF = "browser.newtabpage.activity-stream.asrouter.snippetsUrl";
// Note: currently a restart is required when this pref is changed, this will be fixed in Bug 1462114
const SNIPPETS_ENDPOINT = Services.prefs.getStringPref(SNIPPETS_ENDPOINT_PREF,
"https://activity-stream-icons.services.mozilla.com/v1/messages.json.br");
// List of hosts for endpoints that serve router messages.
// Key is allowed host, value is a name for the endpoint host.
const WHITELIST_HOSTS = {
@ -136,6 +133,35 @@ class _ASRouter {
this.onMessage = this.onMessage.bind(this);
}
_addASRouterPrefListener() {
this.state.providers.forEach(provider => {
if (provider.endpointPref) {
Services.prefs.addObserver(provider.endpointPref, this);
}
});
}
// Update provider endpoint and fetch new messages on pref change
async observe(aSubject, aTopic, aPrefName) {
await this.setState(prevState => {
const providers = [...prevState.providers];
this._updateProviderEndpointUrl(providers.find(p => p.endpointPref === aPrefName));
return {providers};
});
await this.loadMessagesFromAllProviders();
}
_updateProviderEndpointUrl(provider) {
if (provider && provider.endpointPref) {
provider.url = Services.prefs.getStringPref(provider.endpointPref, "");
// Reset provider update timestamp to force messages refresh
provider.lastUpdated = undefined;
}
return provider;
}
get state() {
return this._state;
}
@ -174,7 +200,7 @@ class _ASRouter {
let newState = {messages: [], providers: []};
for (const provider of this.state.providers) {
if (needsUpdate.includes(provider)) {
const {messages, lastUpdated} = await MessageLoaderUtils.loadMessagesForProvider(provider);
const {messages, lastUpdated} = await MessageLoaderUtils.loadMessagesForProvider(this._updateProviderEndpointUrl(provider));
newState.providers.push({...provider, lastUpdated});
newState.messages = [...newState.messages, ...messages];
} else {
@ -199,6 +225,7 @@ class _ASRouter {
async init(channel, storage) {
this.messageChannel = channel;
this.messageChannel.addMessageListener(INCOMING_MESSAGE_NAME, this.onMessage);
this._addASRouterPrefListener();
await this.loadMessagesFromAllProviders();
this._storage = storage;
@ -212,6 +239,11 @@ class _ASRouter {
this.messageChannel.sendAsyncMessage(OUTGOING_MESSAGE_NAME, {type: "CLEAR_ALL"});
this.messageChannel.removeMessageListener(INCOMING_MESSAGE_NAME, this.onMessage);
this.messageChannel = null;
this.state.providers.forEach(provider => {
if (provider.endpointPref) {
Services.prefs.removeObserver(provider.endpointPref, this);
}
});
this._resetInitialization();
}
@ -453,7 +485,7 @@ this._ASRouter = _ASRouter;
this.ASRouter = new _ASRouter({
providers: [
{id: "onboarding", type: "local", messages: OnboardingMessageProvider.getMessages()},
{id: "snippets", type: "remote", url: SNIPPETS_ENDPOINT, updateCycleInMs: ONE_HOUR_IN_MS * 4}
{id: "snippets", type: "remote", endpointPref: SNIPPETS_ENDPOINT_PREF, updateCycleInMs: ONE_HOUR_IN_MS * 4}
]
});

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

@ -168,7 +168,7 @@ const PREFS_CONFIG = new Map([
}],
["asrouter.snippetsUrl", {
title: "A custom URL for the AS router snippets",
value: ""
value: "https://activity-stream-icons.services.mozilla.com/v1/messages.json.br"
}]
]);

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

@ -101,6 +101,10 @@ this.PrefsFeed = class PrefsFeed {
values.isPrivateBrowsingEnabled = PrivateBrowsingUtils.enabled;
values.platform = AppConstants.platform;
// Get the firefox accounts url for links and to send firstrun metrics to.
values.fxa_endpoint = Services.prefs.getStringPref(
"browser.newtabpage.activity-stream.fxaccounts.endpoint", "https://accounts.firefox.com");
// Set the initial state of all prefs in redux
this.store.dispatch(ac.BroadcastToContent({type: at.PREFS_INITIAL_VALUES, data: values}));

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

@ -191,6 +191,8 @@ firstrun_form_sub_header=richin yatok pa Firefox Sync.
firstrun_email_input_placeholder=Taqoya'l
firstrun_invalid_input=Najowäx ütz chi taqoya'l
# 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=Toq nasamajij qa, nawojqaj ri {terms} chuqa' {privacy}.

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

@ -73,7 +73,7 @@ search_header=Αναζήτηση {search_engine_name}
# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
# the user hasn't typed anything yet.
search_web_placeholder=Αναζήτηση στον ιστό
search_web_placeholder=Αναζήτηση στο διαδίκτυο
# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
# the topstories section title to provide additional information about
@ -95,7 +95,7 @@ prefs_home_description=Επιλέξτε τι περιεχόμενο θέλετε
# 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} σειρά;{num} σειρές
prefs_search_header=Αναζήτηση ιστού
prefs_search_header=Διαδικτυακή αναζήτηση
prefs_topsites_description=Οι ιστοσελίδες που επισκέπτεστε περισσότερο
prefs_topstories_description2=Εξαιρετικό περιεχόμενο από το διαδίκτυο, εξατομικευμένο για εσάς
prefs_topstories_options_sponsored_label=Χορηγούμενες ιστορίες

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

@ -191,6 +191,8 @@ firstrun_form_sub_header=por pluiri al Spegulado de Firefox.
firstrun_email_input_placeholder=Retpoŝta adreso
firstrun_invalid_input=Valida retpoŝta adreso postulata
# 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=Se vi daŭrigas vi akceptas la {terms} kaj {privacy}.

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

@ -49,6 +49,7 @@ menu_action_archive_pocket=पॉकेट में पुरालेख
# found in the context menu of an item that has been downloaded. The intention behind
# "this action" is that it will show where the downloaded file exists on the file system
# for each operating system.
menu_action_show_file_mac_os=फाइंडर में दिखाएँ
menu_action_show_file_windows=संग्राहक फोल्डर खोलें
menu_action_show_file_linux=संग्राहक फोल्डर खोलें
menu_action_show_file_default=फ़ाइल दिखाएं
@ -101,6 +102,7 @@ prefs_topstories_options_sponsored_label=प्रायोजित कहा
prefs_topstories_sponsored_learn_more=अधिक जानें
prefs_highlights_description=आपके द्वारा सहेजी गई या विज़िट की गई साइटों का चयन
prefs_highlights_options_visited_label=देखे गए पृष्ठ
prefs_highlights_options_download_label=सबसे हालिया डाउनलोड
prefs_highlights_options_pocket_label=पॉकेट में सहेजे गए पृष्ठ
prefs_snippets_description=Mozilla और Firefox से अद्यतन
settings_pane_button_label=अपने नए टैब पृष्ठ को अनुकूलित करें

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

@ -1,113 +0,0 @@
# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
# of the corresponding content provider.
# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
# the context menu button is focused/active. Title is the label or hostname of
# the site.
# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
# the section edit context menu button is focused/active.
# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
# context on how the element is related to the user, e.g. type indicates that
# the page is bookmarked, or is currently open on another device
# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
# menu and are meant as a call to action for a given page.
# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
# bookmarks"
menu_action_pin=Chita'an
# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
# page from history.
# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
# found in the context menu of an item that has been downloaded. The intention behind
# "this action" is that it will show where the downloaded file exists on the file system
# for each operating system.
menu_action_open_file=Kuna tutu
# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
# link that belongs to this downloaded item"
# LOCALIZATION NOTE (search_button): This is screenreader only text for the
# search button.
search_button=Nduku
# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
# showing search suggestions. {search_engine_name} is replaced with the name of
# the current default search engine. e.g. 'Google Search'
search_header={search_engine_name} Nduku
# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
# the user hasn't typed anything yet.
search_web_placeholder=Nduku nu Web
# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
# the topstories section title to provide additional information about
# how the stories are selected.
# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
# the button used to acknowledge, and hide this disclaimer in the future.
# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
# in English, while "Home" should be localized matching the about:preferences
# sidebar mozilla-central string for the panel that has preferences related to
# what is shown for the homepage, new windows, and new tabs.
# 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
prefs_topstories_sponsored_learn_more=Skua'a kuakaa
# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
# traditionally on about:home. Alternative translation options: "Small Note" or
# something that expresses the idea of "a small message, shortened from
# something else, and non-essential but also not entirely trivial and useless."
# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
# dialog.
edit_topsites_button_text=Sama
# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
topsites_form_url_label=URL
# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
topsites_form_add_button=Chikaa
topsites_form_save_button=Chika vaà
topsites_form_cancel_button=Kunchatu
# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
# trending stories section and precedes a list of links to popular topics.
# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
# end of the list of popular topic links.
# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
# in the space that would have shown a few stories, this is shown instead.
# {provider} is replaced by the name of the content provider for this section.
# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
# import their browser profile from another browser they might be using.
# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
# process of importing another browsers profile into Firefox.
# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
# of importing another browsers profile profile into Firefox.
# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
# action link are shown in each section of UI that fails to render
# LOCALIZATION NOTE (section_menu_action_*). These strings are displayed in the section
# context menu and are meant as a call to action for the given section.
section_menu_action_move_up=Kanta kuchi
section_menu_action_move_down=Kanta ninu
# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
# firstrun of the browser, they give an introduction to Firefox and Sync.
# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
# firstrun_form_header is displayed more boldly as the call to action.
# 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.

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

@ -190,6 +190,8 @@ firstrun_form_sub_header=per contunhar amb Firefox Sync.
firstrun_email_input_placeholder=Adreça electronica
firstrun_invalid_input=Cal una adreça electronica valida
# 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=Se contunhatz, acceptatz las {terms} e l{privacy}.

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

@ -191,6 +191,8 @@ firstrun_form_sub_header=чтобы продолжить использоват
firstrun_email_input_placeholder=Эл. почта
firstrun_invalid_input=Введите действующий адрес электронной почты
# 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=Продолжая, вы соглашаетесь с {terms} и {privacy}.

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

@ -1,32 +1,24 @@
newtab_page_title=නව ටැබය
default_label_loading=පූරණය වෙමින්…
header_top_sites=ප්‍රමුඛ අඩවි
header_stories=ප්‍රමුඛ පුවත්
header_highlights=ඉස්මතු කිරීම්
header_visit_again=යළි පිවිසෙන්න
header_bookmarks=නැවුම් පිටු සලකුණු
# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
# of the corresponding content provider.
header_recommended_by={provider} විසින් නිර්දේශිතයි
# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
# meant to inform that section contains no information because
# the user hasn't added any bookmarks.
header_bookmarks_placeholder=ඔබ සතුව තවම පිටුසලකුණු නැත.
# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
# corresponding content (stories) provider
header_stories_from=සිට​
# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
# the context menu button is focused/active. Title is the label or hostname of
# the site.
# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
# the section edit context menu button is focused/active.
# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
# context on how the element is related to the user, e.g. type indicates that
# the page is bookmarked, or is currently open on another device
type_label_visited=ප්‍රවේශිත
type_label_bookmarked=පිටු සලකුණු තැබූ
type_label_synced=වෙනත් උපාංගයක් වෙතින් සමකාලීන​ කර ඇත​
# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
type_label_open=විවෘත
type_label_topic=මාතෘකාව
type_label_now=දැන්
type_label_pocket=Pocket හි සුරකින ලදී
# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
# menu and are meant as a call to action for a given page.
@ -34,8 +26,6 @@ type_label_now=දැන්
# bookmarks"
menu_action_bookmark=පිටු සලකුණ
menu_action_remove_bookmark=පිටු සලකුණ ඉවත් කරන්න
menu_action_copy_address=ලිපිනය පිටපත් කරන්න
menu_action_email_link=විද්‍යුත් තැපැල් සබැඳි…
menu_action_open_new_window=නව කවුළුවක විවෘත කරන්න
menu_action_open_private_window=නව පුද්ගලික කවුළුවක විවෘත කරන්න
menu_action_dismiss=ඉවත් කරන්න
@ -47,12 +37,18 @@ confirm_history_delete_p1=ඔබට මෙම පිටුවට අදාල
# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
# page from history.
confirm_history_delete_notice_p2=මෙම ක්‍රියාව අහෝසි කළ නොහැක.
menu_action_save_to_pocket=Pocket හි සුරකින්න
menu_action_delete_pocket=Pocket වෙතින් මකන්න
menu_action_archive_pocket=Pocket හි සංරක්ෂණ කරන්න
# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
# for what the user has typed in the search input field, e.g. 'Search for ' +
# search_term + 'with:' becomes 'Search for abc with:'
# The search engine name is displayed as an icon and does not need a translation
search_for_something_with={search_term} සදහා සෙවීමට භාවිත කළ යුත්තේ:
# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
# found in the context menu of an item that has been downloaded. The intention behind
# "this action" is that it will show where the downloaded file exists on the file system
# for each operating system.
# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
# link that belongs to this downloaded item"
# LOCALIZATION NOTE (search_button): This is screenreader only text for the
# search button.
@ -66,13 +62,6 @@ search_header={search_engine_name} ෙසවුම
# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
# the user hasn't typed anything yet.
search_web_placeholder=ජාලය තුළ සොයන්න
search_settings=සෙවුම් සැකසුම් වෙනස් කරන්න
# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
# (?) icon that would show a section's description with optional feedback link.
section_info_option=තොරතුරු
section_info_send_feedback=ප්‍රතිචාරය යවන්න
section_info_privacy_notice=පෞද්ගලිකත්ව දැනුම්දීම්
# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
# the topstories section title to provide additional information about
@ -82,55 +71,42 @@ section_disclaimer_topstories_linktext=එය ක්‍රියාකරන්
# the button used to acknowledge, and hide this disclaimer in the future.
section_disclaimer_topstories_buttontext=හරි, තේරුණා
# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
# first-run experience when there's no data to display yet
welcome_title=නව ටැබයට සාදරයෙන් පිළිගනිමු
welcome_body=ඔබට පහසුවෙන් යළි භාවිතයට පහසු කරවීමට, Firefox මෙම ඉඩ ඔබට වඩාත් අදාල පිටු සළකුණු, ලිපි, විඩියෝ සහ ඔබ මෑතකදී පිවිසි පිටු පෙන්වීම සදහා භාවිත කරයි.
welcome_label=ඔබේ ඉස්මතු කිරීම් හදුනාගනිමින්
# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
time_label_less_than_minute=<1m
time_label_minute={number} මිනිත්තු
time_label_hour={number}පැය
time_label_day={number}දින
# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
# in English, while "Home" should be localized matching the about:preferences
# 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=Firefox මුල්පිටු අන්තර්ගතය
prefs_home_description=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
prefs_section_rows_option={num} තීරය;{num} තීර
prefs_search_header=ජාල සෙවුම
prefs_topsites_description=ඔබ වැඩිපුරම පිවිසෙන අඩවි
prefs_topstories_sponsored_learn_more=තවත් දැනගන්න
settings_pane_button_label=ඔබේ නව ටැබ පිටුව රුචිකරණය කරන්න
settings_pane_header=නව ටැබ අභිප්‍රේත
settings_pane_body2=මෙම පිටුවේ ඔබ දැකිය යුතු දේ තෝරන්න.
settings_pane_search_header=සොයන්න
settings_pane_search_body=ඔබේ නව ටැබයෙන් වෙබ් සෙවීම.
settings_pane_topsites_header=ප්‍රමුඛ අඩවි
settings_pane_topsites_body=ඔබ නිරතුරුව පිවිසෙන වෙබ් අඩවි වෙත ප්‍රවේශය.
settings_pane_topsites_options_showmore=පේළි දෙකක් පෙන්වන්න
settings_pane_bookmarks_header=නැවුම් පිටු සලකුණු
settings_pane_bookmarks_body=ඔබේ නැවුම් පිටු සලකුණු එක් ස්ථානයක.
settings_pane_visit_again_header=යළි පිවිසෙන්න
settings_pane_highlights_header=ඉස්මතු කිරීම්
settings_pane_highlights_options_bookmarks=පිටු සලකුණු
settings_pane_highlights_options_visited=පිවිසුණු අඩවි
# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
# traditionally on about:home. Alternative translation options: "Small Note" or
# something that expresses the idea of "a small message, shortened from
# something else, and non-essential but also not entirely trivial and useless."
settings_pane_topstories_options_sponsored=අනුග්‍රහක පුවත් පෙන්වන්න
# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
# dialog.
edit_topsites_button_text=සැකසුම්
edit_topsites_showmore_button=තවත් පෙන්වන්න
edit_topsites_showless_button=අඩුවෙන් පෙන්වන්න
edit_topsites_done_button=කළා
edit_topsites_edit_button=මෙම අඩවිය සකසන්න
edit_topsites_dismiss_button=මෙම අඩවිය ඉවත ලන්න
edit_topsites_add_button=එක් කරන්න
# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
topsites_form_add_header=නව ප්‍රමුඛ අඩවියක්
topsites_form_edit_header=ප්‍රමුඛ අඩවිය සකසන්න
topsites_form_title_label=මාතෘකාව
topsites_form_title_placeholder=සිරස්තල එක් කරන්න
topsites_form_url_label=URL
topsites_form_url_placeholder=URL එකක් ඇතුළත් කරන්න
# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
topsites_form_add_button=එක් කරන්න
topsites_form_save_button=සුරකින්න
topsites_form_cancel_button=අවලංගු කරන්න
@ -142,10 +118,6 @@ 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=තවත් බොහෝ දැ
# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
# to Pocket as part of the feedback form.
# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
# below (pocket_feedback_header) to provide more information about Pocket.
# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
# in the space that would have shown a few stories, this is shown instead.
@ -160,3 +132,25 @@ manual_migration_cancel_button=එපා, ස්තුතියි
# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
# of importing another browsers profile profile into Firefox.
manual_migration_import_button=දැන් ආයාත කරන්න
# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
# action link are shown in each section of UI that fails to render
# LOCALIZATION NOTE (section_menu_action_*). These strings are displayed in the section
# context menu and are meant as a call to action for the given section.
section_menu_action_move_up=ඉහළට ගෙනයන්න
section_menu_action_move_down=පහළට ගෙනයන්න
section_menu_action_privacy_notice=පෞද්ගලිකත්ව සටහන
# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
# firstrun of the browser, they give an introduction to Firefox and Sync.
# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
# firstrun_form_header is displayed more boldly as the call to action.
# 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.

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

@ -191,6 +191,8 @@ firstrun_form_sub_header=a používajte službu Firefox Sync.
firstrun_email_input_placeholder=E-mail
firstrun_invalid_input=Vyžaduje sa platná e-mailová adresa
# 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=Pokračovaním súhlasíte s {terms} a {privacy}.

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

@ -96,7 +96,7 @@ window.gActivityStreamStrings = {
"firstrun_form_header": "Tatz'ib'aj ri ataqoya'l",
"firstrun_form_sub_header": "richin yatok pa Firefox Sync.",
"firstrun_email_input_placeholder": "Taqoya'l",
"firstrun_invalid_input": "Valid email required",
"firstrun_invalid_input": "Najowäx ütz chi taqoya'l",
"firstrun_extra_legal_links": "Toq nasamajij qa, nawojqaj ri {terms} chuqa' {privacy}.",
"firstrun_terms_of_service": "Kojqanem Samaj",
"firstrun_privacy_notice": "Ichinan Na'oj",

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

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

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

@ -34,14 +34,14 @@ window.gActivityStreamStrings = {
"menu_action_remove_download": "Αφαίρεση από το ιστορικό",
"search_button": "Αναζήτηση",
"search_header": "Αναζήτηση {search_engine_name}",
"search_web_placeholder": "Αναζήτηση στον ιστό",
"search_web_placeholder": "Αναζήτηση στο διαδίκτυο",
"section_disclaimer_topstories": "Οι πιο ενδιαφέρουσες ιστορίες στο διαδίκτυο, επιλεγμένες βάσει όσων διαβάζετε. Από το Pocket, πλέον μέλος της Mozilla.",
"section_disclaimer_topstories_linktext": "Μάθετε πώς λειτουργεί.",
"section_disclaimer_topstories_buttontext": "Εντάξει, το 'πιασα",
"prefs_home_header": "Περιεχόμενο αρχικής σελίδας Firefox",
"prefs_home_description": "Επιλέξτε τι περιεχόμενο θέλετε στην αρχική σελίδα του Firefox σας.",
"prefs_section_rows_option": "{num} σειρά;{num} σειρές",
"prefs_search_header": "Αναζήτηση ιστού",
"prefs_search_header": "Διαδικτυακή αναζήτηση",
"prefs_topsites_description": "Οι ιστοσελίδες που επισκέπτεστε περισσότερο",
"prefs_topstories_description2": "Εξαιρετικό περιεχόμενο από το διαδίκτυο, εξατομικευμένο για εσάς",
"prefs_topstories_options_sponsored_label": "Χορηγούμενες ιστορίες",

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

@ -96,7 +96,7 @@ window.gActivityStreamStrings = {
"firstrun_form_header": "Tajpu vian retpoŝtan adreson",
"firstrun_form_sub_header": "por pluiri al Spegulado de Firefox.",
"firstrun_email_input_placeholder": "Retpoŝta adreso",
"firstrun_invalid_input": "Valid email required",
"firstrun_invalid_input": "Valida retpoŝta adreso postulata",
"firstrun_extra_legal_links": "Se vi daŭrigas vi akceptas la {terms} kaj {privacy}.",
"firstrun_terms_of_service": "kondiĉojn de uzo",
"firstrun_privacy_notice": "rimarkon pri privateco",

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

@ -24,7 +24,7 @@ window.gActivityStreamStrings = {
"menu_action_save_to_pocket": "Pocket में सहेजें",
"menu_action_delete_pocket": "पॉकेट से हटाएं",
"menu_action_archive_pocket": "पॉकेट में पुरालेख",
"menu_action_show_file_mac_os": "Show in Finder",
"menu_action_show_file_mac_os": "फाइंडर में दिखाएँ",
"menu_action_show_file_windows": "संग्राहक फोल्डर खोलें",
"menu_action_show_file_linux": "संग्राहक फोल्डर खोलें",
"menu_action_show_file_default": "फ़ाइल दिखाएं",
@ -48,7 +48,7 @@ window.gActivityStreamStrings = {
"prefs_topstories_sponsored_learn_more": "अधिक जानें",
"prefs_highlights_description": "आपके द्वारा सहेजी गई या विज़िट की गई साइटों का चयन",
"prefs_highlights_options_visited_label": "देखे गए पृष्ठ",
"prefs_highlights_options_download_label": "Most Recent Download",
"prefs_highlights_options_download_label": "सबसे हालिया डाउनलोड",
"prefs_highlights_options_pocket_label": "पॉकेट में सहेजे गए पृष्ठ",
"prefs_snippets_description": "Mozilla और Firefox से अद्यतन",
"settings_pane_button_label": "अपने नए टैब पृष्ठ को अनुकूलित करें",

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

@ -96,7 +96,7 @@ window.gActivityStreamStrings = {
"firstrun_form_header": "Picatz vòstra adreça electronica",
"firstrun_form_sub_header": "per contunhar amb Firefox Sync.",
"firstrun_email_input_placeholder": "Adreça electronica",
"firstrun_invalid_input": "Valid email required",
"firstrun_invalid_input": "Cal una adreça electronica valida",
"firstrun_extra_legal_links": "Se contunhatz, acceptatz las {terms} e l{privacy}.",
"firstrun_terms_of_service": "Condicions dutilizacion",
"firstrun_privacy_notice": "Avís de privacitat",

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

@ -96,7 +96,7 @@ window.gActivityStreamStrings = {
"firstrun_form_header": "Введите ваш адрес электронной почты",
"firstrun_form_sub_header": "чтобы продолжить использовать синхронизацию Firefox.",
"firstrun_email_input_placeholder": "Эл. почта",
"firstrun_invalid_input": "Valid email required",
"firstrun_invalid_input": "Введите действующий адрес электронной почты",
"firstrun_extra_legal_links": "Продолжая, вы соглашаетесь с {terms} и {privacy}.",
"firstrun_terms_of_service": "условиями службы",
"firstrun_privacy_notice": "политикой приватности",

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

@ -9,7 +9,7 @@ window.gActivityStreamStrings = {
"type_label_visited": "ප්‍රවේශිත",
"type_label_bookmarked": "පිටු සලකුණු තැබූ",
"type_label_recommended": "Trending",
"type_label_pocket": "Saved to Pocket",
"type_label_pocket": "Pocket හි සුරකින ලදී",
"type_label_downloaded": "Downloaded",
"menu_action_bookmark": "පිටු සලකුණ",
"menu_action_remove_bookmark": "පිටු සලකුණ ඉවත් කරන්න",
@ -21,9 +21,9 @@ window.gActivityStreamStrings = {
"menu_action_unpin": "ඇමුණුම ඉවත් කරන්න",
"confirm_history_delete_p1": "ඔබට මෙම පිටුවට අදාල සියලුම සිදුවීම් ඔබේ අතීතයන් මැකීමට අවශ්‍ය ද?",
"confirm_history_delete_notice_p2": "මෙම ක්‍රියාව අහෝසි කළ නොහැක.",
"menu_action_save_to_pocket": "Save to Pocket",
"menu_action_delete_pocket": "Delete from Pocket",
"menu_action_archive_pocket": "Archive in Pocket",
"menu_action_save_to_pocket": "Pocket හි සුරකින්න",
"menu_action_delete_pocket": "Pocket වෙතින් මකන්න",
"menu_action_archive_pocket": "Pocket හි සංරක්ෂණ කරන්න",
"menu_action_show_file_mac_os": "Show in Finder",
"menu_action_show_file_windows": "Open Containing Folder",
"menu_action_show_file_linux": "Open Containing Folder",
@ -38,14 +38,14 @@ window.gActivityStreamStrings = {
"section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
"section_disclaimer_topstories_linktext": "එය ක්‍රියාකරන්නේ කෙසේදැයි අධ්‍යපනය කරන්න.",
"section_disclaimer_topstories_buttontext": "හරි, තේරුණා",
"prefs_home_header": "Firefox Home Content",
"prefs_home_description": "Choose what content you want on your Firefox Home screen.",
"prefs_section_rows_option": "{num} row;{num} rows",
"prefs_search_header": "Web Search",
"prefs_topsites_description": "The sites you visit most",
"prefs_home_header": "Firefox මුල්පිටු අන්තර්ගතය",
"prefs_home_description": "Firefox මුල් පිටුවෙහි ඔබට අවැසි වන්නේ කුමන අන්තර්ගතයදැයි තෝරන්න.",
"prefs_section_rows_option": "{num} තීරය;{num} තීර",
"prefs_search_header": "ජාල සෙවුම",
"prefs_topsites_description": "ඔබ වැඩිපුරම පිවිසෙන අඩවි",
"prefs_topstories_description2": "Great content from around the web, personalized for you",
"prefs_topstories_options_sponsored_label": "Sponsored Stories",
"prefs_topstories_sponsored_learn_more": "Learn more",
"prefs_topstories_sponsored_learn_more": "තවත් දැනගන්න",
"prefs_highlights_description": "A selection of sites that youve saved or visited",
"prefs_highlights_options_visited_label": "Visited Pages",
"prefs_highlights_options_download_label": "Most Recent Download",
@ -60,7 +60,7 @@ window.gActivityStreamStrings = {
"edit_topsites_edit_button": "මෙම අඩවිය සකසන්න",
"topsites_form_add_header": "නව ප්‍රමුඛ අඩවියක්",
"topsites_form_edit_header": "ප්‍රමුඛ අඩවිය සකසන්න",
"topsites_form_title_label": "Title",
"topsites_form_title_label": "මාතෘකාව",
"topsites_form_title_placeholder": "සිරස්තල එක් කරන්න",
"topsites_form_url_label": "URL",
"topsites_form_image_url_label": "Custom Image URL",
@ -87,9 +87,9 @@ window.gActivityStreamStrings = {
"section_menu_action_manage_section": "Manage Section",
"section_menu_action_manage_webext": "Manage Extension",
"section_menu_action_add_topsite": "Add Top Site",
"section_menu_action_move_up": "Move Up",
"section_menu_action_move_down": "Move Down",
"section_menu_action_privacy_notice": "Privacy Notice",
"section_menu_action_move_up": "ඉහළට ගෙනයන්න",
"section_menu_action_move_down": "පහළට ගෙනයන්න",
"section_menu_action_privacy_notice": "පෞද්ගලිකත්ව සටහන",
"firstrun_title": "Take Firefox with You",
"firstrun_content": "Get your bookmarks, history, passwords and other settings on all your devices.",
"firstrun_learn_more_link": "Learn more about Firefox Accounts",
@ -101,45 +101,5 @@ window.gActivityStreamStrings = {
"firstrun_terms_of_service": "Terms of Service",
"firstrun_privacy_notice": "Privacy Notice",
"firstrun_continue_to_login": "Continue",
"firstrun_skip_login": "Skip this step",
"default_label_loading": "පූරණය වෙමින්…",
"header_stories": "ප්‍රමුඛ පුවත්",
"header_visit_again": "යළි පිවිසෙන්න",
"header_bookmarks": "නැවුම් පිටු සලකුණු",
"header_bookmarks_placeholder": "ඔබ සතුව තවම පිටුසලකුණු නැත.",
"header_stories_from": "සිට​",
"type_label_synced": "වෙනත් උපාංගයක් වෙතින් සමකාලීන​ කර ඇත​",
"type_label_open": "විවෘත",
"type_label_topic": "මාතෘකාව",
"type_label_now": "දැන්",
"menu_action_copy_address": "ලිපිනය පිටපත් කරන්න",
"menu_action_email_link": "විද්‍යුත් තැපැල් සබැඳි…",
"search_for_something_with": "{search_term} සදහා සෙවීමට භාවිත කළ යුත්තේ:",
"search_settings": "සෙවුම් සැකසුම් වෙනස් කරන්න",
"section_info_option": "තොරතුරු",
"section_info_send_feedback": "ප්‍රතිචාරය යවන්න",
"section_info_privacy_notice": "පෞද්ගලිකත්ව දැනුම්දීම්",
"welcome_title": "නව ටැබයට සාදරයෙන් පිළිගනිමු",
"welcome_body": "ඔබට පහසුවෙන් යළි භාවිතයට පහසු කරවීමට, Firefox මෙම ඉඩ ඔබට වඩාත් අදාල පිටු සළකුණු, ලිපි, විඩියෝ සහ ඔබ මෑතකදී පිවිසි පිටු පෙන්වීම සදහා භාවිත කරයි.",
"welcome_label": "ඔබේ ඉස්මතු කිරීම් හදුනාගනිමින්",
"time_label_less_than_minute": "<1m",
"time_label_minute": "{number} මිනිත්තු",
"time_label_hour": "{number}පැය",
"time_label_day": "{number}දින",
"settings_pane_header": "නව ටැබ අභිප්‍රේත",
"settings_pane_body2": "මෙම පිටුවේ ඔබ දැකිය යුතු දේ තෝරන්න.",
"settings_pane_search_header": "සොයන්න",
"settings_pane_search_body": "ඔබේ නව ටැබයෙන් වෙබ් සෙවීම.",
"settings_pane_topsites_body": "ඔබ නිරතුරුව පිවිසෙන වෙබ් අඩවි වෙත ප්‍රවේශය.",
"settings_pane_topsites_options_showmore": "පේළි දෙකක් පෙන්වන්න",
"settings_pane_bookmarks_header": "නැවුම් පිටු සලකුණු",
"settings_pane_bookmarks_body": "ඔබේ නැවුම් පිටු සලකුණු එක් ස්ථානයක.",
"settings_pane_visit_again_header": "යළි පිවිසෙන්න",
"settings_pane_highlights_options_visited": "පිවිසුණු අඩවි",
"settings_pane_topstories_options_sponsored": "අනුග්‍රහක පුවත් පෙන්වන්න",
"edit_topsites_showmore_button": "තවත් පෙන්වන්න",
"edit_topsites_showless_button": "අඩුවෙන් පෙන්වන්න",
"edit_topsites_done_button": "කළා",
"edit_topsites_dismiss_button": "මෙම අඩවිය ඉවත ලන්න",
"edit_topsites_add_button": "එක් කරන්න"
"firstrun_skip_login": "Skip this step"
};

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

@ -96,7 +96,7 @@ window.gActivityStreamStrings = {
"firstrun_form_header": "Zadajte e-mailovú adresu",
"firstrun_form_sub_header": "a používajte službu Firefox Sync.",
"firstrun_email_input_placeholder": "E-mail",
"firstrun_invalid_input": "Valid email required",
"firstrun_invalid_input": "Vyžaduje sa platná e-mailová adresa",
"firstrun_extra_legal_links": "Pokračovaním súhlasíte s {terms} a {privacy}.",
"firstrun_terms_of_service": "podmienkami používania služby",
"firstrun_privacy_notice": "zásadami ochrany súkromia",

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

@ -12,7 +12,6 @@ import {_ASRouter} from "lib/ASRouter.jsm";
const FAKE_PROVIDERS = [FAKE_LOCAL_PROVIDER, FAKE_REMOTE_PROVIDER];
const ALL_MESSAGE_IDS = [...FAKE_LOCAL_MESSAGES, ...FAKE_REMOTE_MESSAGES].map(message => message.id);
const FAKE_BUNDLE = [FAKE_LOCAL_MESSAGES[1], FAKE_LOCAL_MESSAGES[2]];
// Creates a message object that looks like messages returned by
// RemotePageManager listeners
function fakeAsyncMessage(action) {
@ -26,6 +25,8 @@ describe("ASRouter", () => {
let blockList;
let fetchStub;
let clock;
let getStringPrefStub;
let addObserverStub;
function createFakeStorage() {
return {
@ -47,6 +48,10 @@ describe("ASRouter", () => {
fetchStub = sandbox.stub(global, "fetch")
.withArgs("http://fake.com/endpoint")
.resolves({ok: true, status: 200, json: () => Promise.resolve({messages: FAKE_REMOTE_MESSAGES})});
getStringPrefStub = sandbox.stub(global.Services.prefs, "getStringPref");
getStringPrefStub.returns("http://fake.com/endpoint");
addObserverStub = sandbox.stub(global.Services.prefs, "addObserver");
await createRouterAndInit();
});
afterEach(() => {
@ -67,6 +72,10 @@ describe("ASRouter", () => {
const [, listenerAdded] = channel.addMessageListener.firstCall.args;
assert.isFunction(listenerAdded);
});
it("should add an observer for each provider with a defined endpointPref", () => {
assert.calledOnce(addObserverStub);
assert.calledWith(addObserverStub, "remotePref");
});
it("should set state.blockList to the block list in persistent storage", async () => {
blockList = ["MESSAGE_ID"];
@ -85,6 +94,23 @@ describe("ASRouter", () => {
assert.isArray(Router.state.messages);
assert.lengthOf(Router.state.messages, FAKE_LOCAL_MESSAGES.length + FAKE_REMOTE_MESSAGES.length);
});
it("should call loadMessagesFromAllProviders on pref endpoint change", async () => {
sandbox.spy(Router, "loadMessagesFromAllProviders");
await Router.observe();
assert.calledOnce(Router.loadMessagesFromAllProviders);
});
it("should update provider url on pref change", async () => {
getStringPrefStub.withArgs("remotePref").returns("baz.com");
const {length} = Router.state.providers;
await Router.observe("", "", "remotePref");
const provider = Router.state.providers.find(p => p.url === "baz.com");
assert.lengthOf(Router.state.providers, length);
assert.isDefined(provider);
});
});
describe("#loadMessagesFromAllProviders", () => {
@ -95,6 +121,15 @@ describe("ASRouter", () => {
}
}
it("should load provider endpoint based on pref", async () => {
getStringPrefStub.reset();
getStringPrefStub.returns("example.com");
await createRouterAndInit();
assert.calledOnce(getStringPrefStub);
assert.calledWithExactly(getStringPrefStub, "remotePref", "");
assert.isDefined(Router.state.providers.find(p => p.url === "example.com"));
});
it("should not trigger an update if not enough time has passed for a provider", async () => {
await createRouterAndInit([
{id: "remotey", type: "remote", url: "http://fake.com/endpoint", updateCycleInMs: 300}

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

@ -73,7 +73,7 @@ describe("ASRouterFeed", () => {
prefs[EXPERIMENT_PREF] = true;
// call .onAction with INIT
feed.onAction({type: at.INIT});
feed.onAction({type: at.INIT, data: {name: EXPERIMENT_PREF}});
assert.notCalled(Router.init);
});

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

@ -14,7 +14,7 @@ export const FAKE_LOCAL_PROVIDER = {id: "onboarding", type: "local", messages: F
export const FAKE_REMOTE_MESSAGES = [
{id: "qux", template: "simple_template", content: {title: "Qux", body: "hello world"}}
];
export const FAKE_REMOTE_PROVIDER = {id: "remotey", type: "remote", url: "http://fake.com/endpoint"};
export const FAKE_REMOTE_PROVIDER = {id: "remotey", type: "remote", url: "http://fake.com/endpoint", endpointPref: "remotePref"};
// Stubs methods on RemotePageManager
export class FakeRemotePageManager {