mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 05:45:37 +00:00
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:
parent
826bfa5d74
commit
2d63e9e89f
111
browser/extensions/activity-stream/bin/locales.js
Normal file
111
browser/extensions/activity-stream/bin/locales.js
Normal file
@ -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;
|
||||
|
File diff suppressed because one or more lines are too long
@ -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;
|
||||
|
File diff suppressed because one or more lines are too long
@ -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;
|
||||
|
File diff suppressed because one or more lines are too long
@ -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,
|
||||
" "
|
||||
|
File diff suppressed because one or more lines are too long
@ -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 browser’s profile into Firefox.
|
||||
# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
|
||||
# of importing another browser’s 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 browser’s 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",
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -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 d’utilizacion",
|
||||
"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 you’ve 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 {
|
||||
|
Loading…
Reference in New Issue
Block a user