Bug 1403215 - Fix broken Snippets pref, perceived performance and bug fixes to Activity Stream. r=ursula

MozReview-Commit-ID: JSvQB4nxduM

--HG--
extra : rebase_source : 0a537c181ecf6b5e7fcaa1ced1ae5401abcee018
This commit is contained in:
Ed Lee 2017-09-27 08:28:06 -04:00
Родитель ef6aa2132c
Коммит d9a2f3b235
22 изменённых файлов: 327 добавлений и 122 удалений

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

@ -31,6 +31,7 @@ for (const type of [
"DELETE_HISTORY_URL_CONFIRM",
"DIALOG_CANCEL",
"DIALOG_OPEN",
"DISABLE_ONBOARDING",
"INIT",
"LOCALE_UPDATED",
"MIGRATION_CANCEL",
@ -49,8 +50,8 @@ for (const type of [
"PLACES_BOOKMARK_CHANGED",
"PLACES_BOOKMARK_REMOVED",
"PLACES_HISTORY_CLEARED",
"PLACES_LINKS_DELETED",
"PLACES_LINK_BLOCKED",
"PLACES_LINK_DELETED",
"PREFS_INITIAL_VALUES",
"PREF_CHANGED",
"SAVE_SESSION_PERF_DATA",

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

@ -74,8 +74,7 @@ this.PrerenderData = new _PrerenderData({
icon: "pocket",
id: "topstories",
order: 1,
title: {id: "header_recommended_by", values: {provider: "Pocket"}},
topics: [{}]
title: {id: "header_recommended_by", values: {provider: "Pocket"}}
},
{
enabled: true,

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

@ -288,7 +288,9 @@ function Sections(prevState = INITIAL_STATE.Sections, action) {
return item;
})
}));
case at.PLACES_LINK_DELETED:
case at.PLACES_LINKS_DELETED:
return prevState.map(section => Object.assign({}, section,
{rows: section.rows.filter(site => !action.data.includes(site.url))}));
case at.PLACES_LINK_BLOCKED:
return prevState.map(section =>
Object.assign({}, section, {rows: section.rows.filter(site => site.url !== action.data.url)}));

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

@ -138,9 +138,6 @@
"enabled": true,
"icon": "pocket",
"id": "topstories",
"topics": [
{}
],
"initialized": false
},
{

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

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

@ -94,7 +94,7 @@ const globalImportContext = typeof Window === "undefined" ? BACKGROUND_PROCESS :
// UNINIT: "UNINIT"
// }
const actionTypes = {};
for (const type of ["BLOCK_URL", "BOOKMARK_URL", "DELETE_BOOKMARK_BY_ID", "DELETE_HISTORY_URL", "DELETE_HISTORY_URL_CONFIRM", "DIALOG_CANCEL", "DIALOG_OPEN", "INIT", "LOCALE_UPDATED", "MIGRATION_CANCEL", "MIGRATION_COMPLETED", "MIGRATION_START", "NEW_TAB_INIT", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_REHYDRATED", "NEW_TAB_STATE_REQUEST", "NEW_TAB_UNLOAD", "OPEN_LINK", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_CHANGED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINK_BLOCKED", "PLACES_LINK_DELETED", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "SAVE_SESSION_PERF_DATA", "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", "SECTION_DEREGISTER", "SECTION_DISABLE", "SECTION_ENABLE", "SECTION_OPTIONS_CHANGED", "SECTION_REGISTER", "SECTION_UPDATE", "SECTION_UPDATE_CARD", "SET_PREF", "SHOW_FIREFOX_ACCOUNTS", "SNIPPETS_DATA", "SNIPPETS_RESET", "SYSTEM_TICK", "TELEMETRY_IMPRESSION_STATS", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_ADD", "TOP_SITES_CANCEL_EDIT", "TOP_SITES_EDIT", "TOP_SITES_PIN", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "UNINIT"]) {
for (const type of ["BLOCK_URL", "BOOKMARK_URL", "DELETE_BOOKMARK_BY_ID", "DELETE_HISTORY_URL", "DELETE_HISTORY_URL_CONFIRM", "DIALOG_CANCEL", "DIALOG_OPEN", "DISABLE_ONBOARDING", "INIT", "LOCALE_UPDATED", "MIGRATION_CANCEL", "MIGRATION_COMPLETED", "MIGRATION_START", "NEW_TAB_INIT", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_REHYDRATED", "NEW_TAB_STATE_REQUEST", "NEW_TAB_UNLOAD", "OPEN_LINK", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_CHANGED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINKS_DELETED", "PLACES_LINK_BLOCKED", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "SAVE_SESSION_PERF_DATA", "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", "SECTION_DEREGISTER", "SECTION_DISABLE", "SECTION_ENABLE", "SECTION_OPTIONS_CHANGED", "SECTION_REGISTER", "SECTION_UPDATE", "SECTION_UPDATE_CARD", "SET_PREF", "SHOW_FIREFOX_ACCOUNTS", "SNIPPETS_DATA", "SNIPPETS_RESET", "SYSTEM_TICK", "TELEMETRY_IMPRESSION_STATS", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_ADD", "TOP_SITES_CANCEL_EDIT", "TOP_SITES_EDIT", "TOP_SITES_PIN", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "UNINIT"]) {
actionTypes[type] = type;
}
@ -638,7 +638,8 @@ function Sections(prevState = INITIAL_STATE.Sections, action) {
return item;
})
}));
case at.PLACES_LINK_DELETED:
case at.PLACES_LINKS_DELETED:
return prevState.map(section => Object.assign({}, section, { rows: section.rows.filter(site => !action.data.includes(site.url)) }));
case at.PLACES_LINK_BLOCKED:
return prevState.map(section => Object.assign({}, section, { rows: section.rows.filter(site => site.url !== action.data.url) }));
default:
@ -1511,10 +1512,14 @@ class TopSitesEdit extends React.PureComponent {
"section",
{ className: "edit-topsites-inner-wrapper" },
React.createElement(
"h3",
{ className: "section-title" },
React.createElement("span", { className: `icon icon-small-spacer icon-topsites` }),
React.createElement(FormattedMessage, { id: "header_top_sites" })
"div",
{ className: "section-top-bar" },
React.createElement(
"h3",
{ className: "section-title" },
React.createElement("span", { className: `icon icon-small-spacer icon-topsites` }),
React.createElement(FormattedMessage, { id: "header_top_sites" })
)
),
React.createElement(
"ul",
@ -2569,7 +2574,10 @@ class Section extends React.PureComponent {
contextMenuOptions, intl, initialized
} = this.props;
const maxCards = CARDS_PER_ROW * maxRows;
const shouldShowTopics = id === "topstories" && this.props.topics && this.props.topics.length > 0;
// Show topics only for top stories and if it's not initialized yet (so
// content doesn't shift when it is loaded) or has loaded with topics
const shouldShowTopics = id === "topstories" && (!this.props.topics || this.props.topics.length > 0);
const infoOptionIconA11yAttrs = {
"aria-haspopup": "true",
@ -2694,6 +2702,9 @@ const { FormattedMessage } = __webpack_require__(2);
const cardContextTypes = __webpack_require__(26);
const { actionCreators: ac, actionTypes: at } = __webpack_require__(0);
// Keep track of pending image loads to only request once
const gImageLoading = new Map();
/**
* Card component.
* Cards are found within a Section component and contain information about a link such
@ -2706,11 +2717,47 @@ const { actionCreators: ac, actionTypes: at } = __webpack_require__(0);
class Card extends React.PureComponent {
constructor(props) {
super(props);
this.state = { showContextMenu: false, activeCard: null };
this.state = {
activeCard: null,
imageLoaded: false,
showContextMenu: false
};
this.onMenuButtonClick = this.onMenuButtonClick.bind(this);
this.onMenuUpdate = this.onMenuUpdate.bind(this);
this.onLinkClick = this.onLinkClick.bind(this);
}
/**
* Helper to conditionally load an image and update state when it loads.
*/
async maybeLoadImage() {
// No need to load if it's already loaded or no image
const { image } = this.props.link;
if (!this.state.imageLoaded && image) {
// Initialize a promise to share a load across multiple card updates
if (!gImageLoading.has(image)) {
const loaderPromise = new Promise((resolve, reject) => {
const loader = new Image();
loader.addEventListener("load", resolve);
loader.addEventListener("error", reject);
loader.src = image;
});
// Save and remove the promise only while it's pending
gImageLoading.set(image, loaderPromise);
loaderPromise.catch(ex => ex).then(() => gImageLoading.delete(image)).catch();
}
// Wait for the image whether just started loading or reused promise
await gImageLoading.get(image);
// Only update state if we're still waiting to load the original image
if (this.props.link.image === image && !this.state.imageLoaded) {
this.setState({ imageLoaded: true });
}
}
}
onMenuButtonClick(event) {
event.preventDefault();
this.setState({
@ -2742,6 +2789,18 @@ class Card extends React.PureComponent {
onMenuUpdate(showContextMenu) {
this.setState({ showContextMenu });
}
componentDidMount() {
this.maybeLoadImage();
}
componentDidUpdate() {
this.maybeLoadImage();
}
componentWillReceiveProps(nextProps) {
// Clear the image state if changing images
if (nextProps.link.image !== this.props.link.image) {
this.setState({ imageLoaded: false });
}
}
render() {
const { index, link, dispatch, contextMenuOptions, eventSource, shouldSendImpressionStats } = this.props;
const { props } = this;
@ -2763,7 +2822,7 @@ class Card extends React.PureComponent {
hasImage && React.createElement(
"div",
{ className: "card-preview-image-outer" },
React.createElement("div", { className: `card-preview-image${link.image ? " loaded" : ""}`, style: imageStyle })
React.createElement("div", { className: `card-preview-image${this.state.imageLoaded ? " loaded" : ""}`, style: imageStyle })
),
React.createElement(
"div",
@ -2894,7 +2953,7 @@ class Topics extends React.PureComponent {
React.createElement(
"ul",
null,
topics.map(t => React.createElement(Topic, { key: t.name, url: t.url, name: t.name }))
topics && topics.map(t => React.createElement(Topic, { key: t.name, url: t.url, name: t.name }))
),
read_more_endpoint && React.createElement(
"a",
@ -2985,8 +3044,7 @@ var PrerenderData = new _PrerenderData({
icon: "pocket",
id: "topstories",
order: 1,
title: { id: "header_recommended_by", values: { provider: "Pocket" } },
topics: [{}]
title: { id: "header_recommended_by", values: { provider: "Pocket" } }
}, {
enabled: true,
id: "highlights",
@ -3257,6 +3315,10 @@ class SnippetsMap extends Map {
await this.set("blockList", blockList);
}
disableOnboarding() {
this._dispatch(ac.SendToMain({ type: at.DISABLE_ONBOARDING }));
}
showFirefoxAccounts() {
this._dispatch(ac.SendToMain({ type: at.SHOW_FIREFOX_ACCOUNTS }));
}
@ -3395,7 +3457,6 @@ class SnippetsProvider {
if (needsUpdate && this.appData.snippetsURL) {
this.snippetsMap.set("snippets-last-update", Date.now());
try {
// TODO: timeout?
const response = await fetch(this.appData.snippetsURL);
if (response.status === 200) {
const payload = await response.text();
@ -3409,10 +3470,18 @@ class SnippetsProvider {
}
}
_showDefaultSnippets() {
_noSnippetFallback() {
// TODO
}
_forceOnboardingVisibility(shouldBeVisible) {
const onboardingEl = document.getElementById("onboarding-notification-bar");
if (onboardingEl) {
onboardingEl.style.display = shouldBeVisible ? "" : "none";
}
}
_showRemoteSnippets() {
const snippetsEl = document.getElementById(this.elementId);
const payload = this.snippetsMap.get("snippets");
@ -3480,15 +3549,18 @@ class SnippetsProvider {
try {
this._showRemoteSnippets();
} catch (e) {
this._showDefaultSnippets(e);
this._noSnippetFallback(e);
}
window.dispatchEvent(new Event(SNIPPETS_ENABLED_EVENT));
this._forceOnboardingVisibility(true);
this.initialized = true;
}
uninit() {
window.dispatchEvent(new Event(SNIPPETS_DISABLED_EVENT));
this._forceOnboardingVisibility(false);
this.initialized = false;
}
}
@ -3508,16 +3580,16 @@ function addSnippetsSubscriber(store) {
store.subscribe(async () => {
const state = store.getState();
// state.Snippets.initialized: Should snippets be initialised?
// snippets.initialized: Is SnippetsProvider currently initialised?
if (state.Snippets.initialized && !snippets.initialized && state.Snippets.onboardingFinished) {
// Don't call init multiple times
if (!initializing) {
initializing = true;
await snippets.init({ appData: state.Snippets });
initializing = false;
}
} else if (state.Snippets.initialized === false && snippets.initialized) {
// state.Prefs.values["feeds.snippets"]: Should snippets be shown?
// state.Snippets.initialized Is the snippets data initialized?
// snippets.initialized: Is SnippetsProvider currently initialised?
if (state.Prefs.values["feeds.snippets"] && state.Snippets.initialized && !snippets.initialized &&
// Don't call init multiple times
!initializing) {
initializing = true;
await snippets.init({ appData: state.Snippets });
initializing = false;
} else if (state.Prefs.values["feeds.snippets"] === false && snippets.initialized) {
snippets.uninit();
}
});

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

@ -457,26 +457,24 @@ main {
padding-inline-start: 3px; }
.topsite-form .form-wrapper {
margin: auto;
max-width: 350px;
padding: 15px 0; }
.topsite-form .form-wrapper .field {
margin-inline-start: 205px;
position: relative; }
.topsite-form .form-wrapper .url input:not(:placeholder-shown):dir(rtl) {
direction: ltr;
text-align: right; }
.topsite-form .form-wrapper .section-title {
margin-bottom: 5px;
margin-inline-start: 205px; }
margin-bottom: 5px; }
.topsite-form .form-wrapper input[type='text'] {
border: solid 1px rgba(12, 12, 13, 0.2);
border-radius: 2px;
margin: 5px 0;
padding: 7px;
width: 350px; }
width: 100%; }
.topsite-form .form-wrapper input[type='text']:focus {
border: solid 1px rgba(12, 12, 13, 0.4); }
.topsite-form .form-wrapper input[type='text']::placeholder {
font-style: italic; }
.topsite-form .form-wrapper .invalid input[type='text'] {
border: solid 1px #D70022;
box-shadow: 0 0 0 2px rgba(215, 0, 34, 0.35); }
@ -676,28 +674,19 @@ main {
width: 100%;
height: 36px; }
.search-wrapper input {
border: 0;
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
border: 1px solid rgba(0, 0, 0, 0.15);
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
border-radius: 3px;
border-radius: 4px;
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
color: inherit;
padding: 0;
padding-inline-end: 36px;
padding-inline-start: 35px;
width: 100%;
font-size: 15px; }
.search-wrapper input:focus {
border-color: #0060DF;
box-shadow: 0 0 0 2px #0060DF;
z-index: 1; }
.search-wrapper input:focus + .search-button {
z-index: 1;
background-color: #0060DF;
background-image: url("chrome://browser/skin/forward.svg");
fill: #FFF;
-moz-context-properties: fill; }
.search-wrapper:active input,
.search-wrapper input:focus {
border-color: #0A84FF;
box-shadow: 0 0 0 2px #0A84FF; }
.search-wrapper .search-label {
background: url("chrome://browser/skin/search-glass.svg") no-repeat 12px center/16px;
fill: rgba(12, 12, 13, 0.4);
@ -705,8 +694,7 @@ main {
position: absolute;
offset-inline-start: 0;
height: 100%;
width: 35px;
z-index: 2; }
width: 35px; }
.search-wrapper .search-button {
background: url("chrome://browser/skin/forward.svg") no-repeat center center;
border-radius: 0 3px 3px 0;
@ -718,11 +706,11 @@ main {
height: 100%;
offset-inline-end: 0;
position: absolute; }
.search-wrapper .search-button:hover {
z-index: 1;
background-color: #0060DF;
fill: #FFF;
.search-wrapper .search-button:focus, .search-wrapper .search-button:hover {
background-color: rgba(12, 12, 13, 0.1);
cursor: pointer; }
.search-wrapper .search-button:active {
background-color: rgba(12, 12, 13, 0.15); }
.search-wrapper .search-button:dir(rtl) {
transform: scaleX(-1); }
.search-wrapper .contentSearchSuggestionTable {
@ -1009,13 +997,11 @@ main {
.card-outer:-moz-any(:hover, :focus, .active):not(.placeholder) .card-title {
color: #0060DF; }
.card-outer .card-preview-image-outer {
background-color: #F9F9FA;
position: relative;
background: linear-gradient(135deg, #B1B1B3, #D7D7DB);
height: 122px;
border-radius: 3px 3px 0 0;
overflow: hidden; }
.card-outer .card-preview-image-outer:dir(rtl) {
background: linear-gradient(225deg, #B1B1B3, #D7D7DB); }
.card-outer .card-preview-image-outer::after {
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
bottom: 0;
@ -1028,8 +1014,8 @@ main {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
transition: opacity 1s;
opacity: 0; }
opacity: 0;
transition: opacity 1s cubic-bezier(0.07, 0.95, 0, 1); }
.card-outer .card-preview-image-outer .card-preview-image.loaded {
opacity: 1; }
.card-outer .card-details {

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

@ -580,7 +580,51 @@
"time_label_hour": "{number}e",
"time_label_day": "{number}d",
"settings_pane_button_label": "Personelait ho pajenn Ivinell Nevez",
"settings_pane_header": "Gwellvezioù an ivinell nevez"
"settings_pane_header": "Gwellvezioù an ivinell nevez",
"settings_pane_body2": "Dibabit petra a welit war ar bajenn-mañ.",
"settings_pane_search_header": "Klask",
"settings_pane_search_body": "Klask er web adalek an ivinell nevez.",
"settings_pane_topsites_header": "Lec'hiennoù gwellañ",
"settings_pane_topsites_body": "Kit war al lec'hiennoù gweladennet ar muiañ ganeoc'h.",
"settings_pane_topsites_options_showmore": "Diskouez daou vann",
"settings_pane_bookmarks_header": "Sinedoù nevez",
"settings_pane_bookmarks_body": "Ho sinedoù nevez strollet en ul lec'h aes da dizhout.",
"settings_pane_visit_again_header": "Gweladenniñ en-dro",
"settings_pane_visit_again_body": "Firefox a ziskouezo deoc'h ul lodenn eus ho roll istor a c'hallfec'h kaout c'hoant da zerc'hel soñj pe da zistreiñ eno.",
"settings_pane_highlights_header": "Mareoù pouezus",
"settings_pane_highlights_body2": "Adkavit an traoù dedennus gweladennet pe lakaet er sinedoù nevez zo.",
"settings_pane_highlights_options_bookmarks": "Sinedoù",
"settings_pane_highlights_options_visited": "Lec'hiennoù gweladennet",
"settings_pane_snippets_header": "Notennigoù",
"settings_pane_snippets_body": "Lennit an hizivadurioù berr ha dous graet gant Mozilla evit Firefox, sevenadur ar genrouedad, hag ur mem dre-zegouezh ur wech an amzer.",
"settings_pane_done_button": "Graet",
"edit_topsites_button_text": "Embann",
"edit_topsites_button_label": "Personelaat ar gevrenn “lec'hiennoù gweladennet ar muiañ”",
"edit_topsites_showmore_button": "Diskouez muioc'h",
"edit_topsites_showless_button": "Diskouez nebeutoc'h",
"edit_topsites_done_button": "Graet",
"edit_topsites_pin_button": "Spilhennañ al lec'hienn-mañ",
"edit_topsites_unpin_button": "Dispilhennañ al lec'hienn-mañ",
"edit_topsites_edit_button": "Embann al lec'hienn-mañ",
"edit_topsites_dismiss_button": "Dilemel al lec'hienn-mañ",
"edit_topsites_add_button": "Ouzhpennañ",
"topsites_form_add_header": "Lec'hiennoù gwellañ nevez",
"topsites_form_edit_header": "Embann al Lec'hiennoù Gwellañ",
"topsites_form_title_placeholder": "Enankañ un titl",
"topsites_form_url_placeholder": "Skrivit pe pegit un URL",
"topsites_form_add_button": "Ouzhpennañ",
"topsites_form_save_button": "Enrollañ",
"topsites_form_cancel_button": "Nullañ",
"topsites_form_url_validation": "URL talvoudek azgoulennet",
"pocket_read_more": "Danvezioù brudet:",
"pocket_read_even_more": "Gwelet muioc'h a istorioù",
"pocket_feedback_header": "Ar gwellañ eus ar web, dibabet gant ouzhpenn 25 milion a dud.",
"pocket_description": "Dizoloit pennadoù eus an dibab ho pije gellout c'hwitout a-hent all warno, a-drugarez da bPocket, hag a zo bremañ ul lodenn deus Mozilla.",
"highlights_empty_state": "Krogit da verdeiñ hag e tiskouezimp deoch pennadoù, videoioù ha pajennoù all gweladennet pe lakaet er sinedoù nevez zo.",
"topstories_empty_state": "Aet oc'h betek penn. Distroit diwezhatoc'h evit muioch a istorioù digant {provider}. Noc'h ket evit gortoz? Dibabit un danvez brudet evit klask muioch a bennadoù dedennus eus pep lech er web.",
"manual_migration_explanation2": "Amprouit Firefox gant sinedoù, roll istor ha gerioù-tremen ur merdeer all.",
"manual_migration_cancel_button": "N'am bo ket",
"manual_migration_import_button": "Emporzhiañ bremañ"
},
"ca": {
"newtab_page_title": "Pestanya nova",
@ -955,6 +999,7 @@
"default_label_loading": "Indlæser…",
"header_top_sites": "Mest besøgte websider",
"header_stories": "Tophistorier",
"header_highlights": "Højdepunkter",
"header_visit_again": "Besøg igen",
"header_bookmarks": "Seneste bogmærker",
"header_recommended_by": "Anbefalet af {provider}",
@ -986,6 +1031,7 @@
"search_web_placeholder": "Søg på internettet",
"search_settings": "Skift søgeindstillinger",
"section_info_option": "Info",
"section_info_send_feedback": "Send feedback",
"welcome_title": "Velkommen til nyt faneblad",
"welcome_body": "Firefox vil bruge denne plads til at vise dine mest relevante bogmærker, artikler, videoer og sider, du har besøgt for nylig - så kan du nemmere finde dem.",
"welcome_label": "Finder dine højdepunkter",
@ -995,7 +1041,6 @@
"time_label_day": "{number} d.",
"settings_pane_button_label": "Tilpas siden Nyt faneblad",
"settings_pane_header": "Indstillinger for Nyt faneblad",
"settings_pane_body": "Vælg, hvad der vises, når du åbner et nyt faneblad.",
"settings_pane_search_header": "Søgning",
"settings_pane_search_body": "Søg på nettet fra Nyt faneblad.",
"settings_pane_topsites_header": "Mest besøgte websider",
@ -1005,8 +1050,6 @@
"settings_pane_bookmarks_body": "Dine seneste bogmærker samlet ét sted.",
"settings_pane_visit_again_header": "Besøg igen",
"settings_pane_visit_again_body": "Firefox viser dig dele af din browserhistorik, som du måske vil huske på eller vende tilbage til.",
"settings_pane_pocketstories_header": "Tophistorier",
"settings_pane_pocketstories_body": "Pocket, en del af Mozilla-familien, hjælper dig med at opdage indhold af høj kvalitet, som du måske ellers ikke ville have fundet.",
"settings_pane_done_button": "Færdig",
"edit_topsites_button_text": "Rediger",
"edit_topsites_button_label": "Tilpas afsnittet Mest besøgte websider",
@ -1029,10 +1072,7 @@
"pocket_read_more": "Populære emner:",
"pocket_read_even_more": "Se flere historier",
"pocket_feedback_header": "Det bedste fra nettet, udvalgt af mere end 25 millioner mennesker.",
"pocket_feedback_body": "Pocket, en del af Mozilla-familien, hjælper dig med at opdage indhold af høj kvalitet, som du måske ellers ikke ville have fundet.",
"pocket_send_feedback": "Send feedback",
"topstories_empty_state": "Der er ikke flere nye historier. Kom tilbage senere for at se flere tophistorier fra {provider}. Kan du ikke vente? Vælg et populært emne og find flere spændende historier fra hele verden.",
"manual_migration_explanation": "Prøv Firefox med dine favorit-websteder og bogmærker fra en anden browser.",
"manual_migration_cancel_button": "Nej tak",
"manual_migration_import_button": "Importer nu"
},
@ -3788,8 +3828,8 @@
"kk": {
"newtab_page_title": "Жаңа бет",
"default_label_loading": "Жүктелуде…",
"header_top_sites": "Топ сайттар",
"header_stories": "Топ хикаялар",
"header_top_sites": "Үздік сайттар",
"header_stories": "Үздік хикаялар",
"header_highlights": "Ерекше жаңалықтар",
"header_visit_again": "Қайтадан шолу",
"header_bookmarks": "Соңғы бетбелгілер",
@ -3815,7 +3855,7 @@
"menu_action_unpin": "Бекітуді алып тастау",
"confirm_history_delete_p1": "Бұл парақтың барлық кездесулерін шолу тарихыңыздан өшіруді қалайсыз ба?",
"confirm_history_delete_notice_p2": "Бұл әрекетті болдырмау мүмкін болмайды.",
"menu_action_save_to_pocket": "Pocketе сақтау",
"menu_action_save_to_pocket": "Pocket ішіне сақтау",
"search_for_something_with": "{search_term} ұғымын көмегімен іздеу:",
"search_button": "Іздеу",
"search_header": "{search_engine_name} іздеуі",
@ -3833,10 +3873,10 @@
"time_label_day": "{number} күн",
"settings_pane_button_label": "Жаңа бетті баптаңыз",
"settings_pane_header": "Жаңа бет баптаулары",
"settings_pane_body2": "Бұл парақта не көргіңіз келетінді таңдаңыз.",
"settings_pane_body2": "Бұл бетте не көргіңіз келетінді таңдаңыз.",
"settings_pane_search_header": "Іздеу",
"settings_pane_search_body": "Жаңа беттен интернеттен іздеңіз.",
"settings_pane_topsites_header": "Топ сайттар",
"settings_pane_topsites_header": "Үздік сайттар",
"settings_pane_topsites_body": "Көбірек қаралатын сайттарға қатынау.",
"settings_pane_topsites_options_showmore": "Екі жолды көрсету",
"settings_pane_bookmarks_header": "Соңғы бетбелгілер",
@ -3848,7 +3888,7 @@
"settings_pane_highlights_options_bookmarks": "Бетбелгілер",
"settings_pane_highlights_options_visited": "Ашылған сайттар",
"settings_pane_snippets_header": "Үзінділер",
"settings_pane_snippets_body": "Mozillaан Firefox және интернет мәдениеті туралы қысқа жаңалықтарды, және кездейсоқ мемдерді оқыңыз.",
"settings_pane_snippets_body": "Mozilla ұсынған Firefox және интернет мәдениеті туралы қысқа жаңалықтарды, және кездейсоқ мемдерді оқыңыз.",
"settings_pane_done_button": "Дайын",
"edit_topsites_button_text": "Түзету",
"edit_topsites_button_label": "Топ сайттар санатын баптау",
@ -3874,7 +3914,7 @@
"pocket_description": "Ол болмаса, сіз жіберіп алатын мүмкіндігі бар жоғары сапалы құраманы Pocket көмегімен табыңыз, ол енді Mozilla-ның бөлігі болып табылады.",
"highlights_empty_state": "Шолуды бастаңыз, сіз жақында шолған немесе бетбелгілерге қосқан тамаша мақалалар, видеолар немесе басқа парақтардың кейбіреулері осында көрсетіледі.",
"topstories_empty_state": "Дайын. {provider} ұсынған көбірек мақалаларды алу үшін кейінірек тексеріңіз. Күте алмайсыз ба? Интернеттен көбірек тамаша мақалаларды алу үшін әйгілі теманы таңдаңыз.",
"manual_migration_explanation2": "Firefox-ты басқа браузер бетбелгілері, тарихы және парольдерімен қолданып көріңіз.",
"manual_migration_explanation2": "Firefox қолданбасын басқа браузер бетбелгілері, тарихы және парольдерімен қолданып көріңіз.",
"manual_migration_cancel_button": "Жоқ, рахмет",
"manual_migration_import_button": "Қазір импорттау"
},
@ -4203,13 +4243,15 @@
"manual_migration_import_button": "Importuoti dabar"
},
"lv": {
"newtab_page_title": "Jauna cilne"
"newtab_page_title": "Jauna cilne",
"default_label_loading": "Notiek ielāde…"
},
"mk": {
"newtab_page_title": "Ново јазиче",
"default_label_loading": "Се вчитува…",
"header_top_sites": "Врвни мрежни места",
"header_stories": "Врвни написи",
"header_top_sites": "Популарни мрежни места",
"header_stories": "Популарни написи",
"header_highlights": "Интереси",
"header_visit_again": "Посети повторно",
"header_bookmarks": "Скорешни обележувачи",
"header_recommended_by": "Препорачано од {provider}",
@ -4232,7 +4274,7 @@
"menu_action_delete": "Избриши од историја",
"menu_action_pin": "Прикачи",
"menu_action_unpin": "Откачи",
"confirm_history_delete_p1": "Дали сте сигурни дека сакате да ја избришете оваа страница отсекаде во Вашата историја на прелистување?",
"confirm_history_delete_p1": "Дали сте сигурни дека сакате да ја избришете оваа страница отсекаде во вашата историја на прелистување?",
"confirm_history_delete_notice_p2": "Ова дејство не може да се одврати.",
"menu_action_save_to_pocket": "Зачувај во Pocket",
"search_for_something_with": "Пребарај за {search_term} со:",
@ -4241,30 +4283,36 @@
"search_web_placeholder": "Пребарајте на Интернет",
"search_settings": "Промени поставувања за пребарување",
"section_info_option": "Инфо",
"section_info_send_feedback": "Испрати мислење",
"section_info_privacy_notice": "Белешка за приватност",
"welcome_title": "Добредојдовте во новото јазиче",
"welcome_body": "Firefox ќе го искористи овој простор за да Ви ги прикаже најрелевантните обележувачи, написи, видеа и страници што сте ги посетиле, за да можете лесно да им се навратите.",
"welcome_label": "Ги откривам Вашите интереси",
"welcome_label": "Ги откривам вашите Интереси",
"time_label_less_than_minute": "< 1 м",
"time_label_minute": "{number} м",
"time_label_hour": "{number} ч",
"time_label_day": "{number} д",
"settings_pane_button_label": "Прилагодете ја страницата на Вашето Ново јазиче",
"settings_pane_button_label": "Прилагодете ја страницата на вашето Ново јазиче",
"settings_pane_header": "Преференци за Ново јазиче",
"settings_pane_body": "Изберете што ќе гледате кога ќе отворите ново јазиче.",
"settings_pane_body2": "Изберете што ќе гледате на оваа страница.",
"settings_pane_search_header": "Пребарување",
"settings_pane_search_body": "Пребарајте низ Интернет од Вашето ново јазиче.",
"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_visit_again_body": "Firefox ќе прикаже делови од Вашата историја на прелистување кои можеби би сакале да ги запомните или пак да им се навратите.",
"settings_pane_pocketstories_header": "Врвни написи",
"settings_pane_pocketstories_body": "Pocket, дел од семејството на Mozilla, ќе Ви помогне да стигнете до високо-квалитетни содржини кои можеби не би ги откриле на друг начин.",
"settings_pane_visit_again_body": "Firefox ќе прикаже делови од вашата историја на прелистување кои можеби би сакале да ги запомните или пак да им се навратите.",
"settings_pane_highlights_header": "Интереси",
"settings_pane_highlights_body2": "Навратете се на интересни места што неодамна сте ги посетиле или обележале.",
"settings_pane_highlights_options_bookmarks": "Обележувачи",
"settings_pane_highlights_options_visited": "Посетени мрежни места",
"settings_pane_snippets_header": "Исечоци",
"settings_pane_snippets_body": "Прочитајте кратки и слатки новости од Mozilla во врска со Firefox, Интернет-културата и повремените случајни меми.",
"settings_pane_done_button": "Готово",
"edit_topsites_button_text": "Уреди",
"edit_topsites_button_label": "Прилагодете ги Вашите Врвни мрежни места",
"edit_topsites_button_label": "Прилагодете ги вашите Популарни мрежни места",
"edit_topsites_showmore_button": "Прикажи повеќе",
"edit_topsites_showless_button": "Прикажи помалку",
"edit_topsites_done_button": "Готово",
@ -4284,10 +4332,10 @@
"pocket_read_more": "Популарни теми:",
"pocket_read_even_more": "Види повеќе написи",
"pocket_feedback_header": "Најдоброто од Интернет, одбрано од повеќе од 25 милиони луѓе.",
"pocket_feedback_body": "Pocket, дел од семејството на Mozilla, ќе Ви помогне да стигнете до високо-квалитетни содржини кои можеби не би ги откриле на друг начин.",
"pocket_send_feedback": "Остави коментар",
"pocket_description": "Откријте високо-квалитетни содржини, коишто инаку би можеле да ги пропуштите, со помош на Pocket, кој сега е дел од Mozilla.",
"highlights_empty_state": "Започнете со прелистување и ние овде ќе ви прикажеме некои од одличните написи, видеа и други страници што неодамна сте ги поселите или обележале.",
"topstories_empty_state": "Имате видено сѐ! Навратете се подоцна за нови содржини од {provider}. Не можете да чекате? Изберете популарна тема и откријте уште одлични содржини ширум Интернет.",
"manual_migration_explanation": "Пробајте го Firefox со Вашите омилени мрежни места и обележувачи од друг прелистувач.",
"manual_migration_explanation2": "Пробајте го Firefox со обележувачите, историјата и лозинките на друг прелистувач.",
"manual_migration_cancel_button": "Не, благодарам",
"manual_migration_import_button": "Увези сега"
},
@ -6092,7 +6140,7 @@
"header_stories": "เรื่องราวเด่น",
"header_highlights": "รายการเด่น",
"header_visit_again": "เยี่ยมชมอีกครั้ง",
"header_bookmarks": "ที่คั่นหน้าเมื่อเร็ว ๆ นี้",
"header_bookmarks": "ที่คั่นหน้าล่าสุด",
"header_recommended_by": "แนะนำโดย {provider}",
"header_bookmarks_placeholder": "คุณยังไม่มีที่คั่นหน้าใด ๆ",
"header_stories_from": "จาก",
@ -6139,7 +6187,7 @@
"settings_pane_topsites_header": "ไซต์เด่น",
"settings_pane_topsites_body": "เข้าถึงเว็บไซต์ที่คุณเยี่ยมชมมากที่สุด",
"settings_pane_topsites_options_showmore": "แสดงสองแถว",
"settings_pane_bookmarks_header": "ที่คั่นหน้าเมื่อเร็ว ๆ นี้",
"settings_pane_bookmarks_header": "ที่คั่นหน้าล่าสุด",
"settings_pane_bookmarks_body": "ที่คั่นหน้าที่สร้างใหม่ของคุณในตำแหน่งที่ตั้งเดียวที่สะดวก",
"settings_pane_visit_again_header": "เยี่ยมชมอีกครั้ง",
"settings_pane_highlights_header": "รายการเด่น",
@ -6617,8 +6665,8 @@
"settings_pane_highlights_body2": "根据您最近访问的页面和添加的书签推荐您感兴趣的东西。",
"settings_pane_highlights_options_bookmarks": "书签",
"settings_pane_highlights_options_visited": "访问过的网站",
"settings_pane_snippets_header": "板报",
"settings_pane_snippets_body": "阅读和了解 Mozilla 就 Firefox、互联网文化等提供的一些简短而有趣的更新。",
"settings_pane_snippets_header": "只言片语",
"settings_pane_snippets_body": "阅读 Mozilla 就 Firefox、互联网文化、偶尔还有模因提供的一些简短而有趣的小文章。",
"settings_pane_done_button": "完成",
"edit_topsites_button_text": "编辑",
"edit_topsites_button_label": "定制您的“常用网站”区域",
@ -6641,7 +6689,7 @@
"pocket_read_more": "热门主题:",
"pocket_read_even_more": "查看更多文章",
"pocket_feedback_header": "由超过 2500 万人挑选出来的网上精华内容。",
"pocket_description": "借助 Pocket目前所属 Mozilla发现有趣的高品质内容。",
"pocket_description": "借助 Pocket目前属 Mozilla 旗下)发现您不容错过的高品质内容。",
"highlights_empty_state": "开始浏览旅程吧,之后这里会显示您最近看过或加了书签的精彩文章、视频以及其他页面。",
"topstories_empty_state": "所有文章都读完啦!晚点再来,{provider} 将推荐更多热门文章。等不及了?选择一个热门话题,找到更多网上的好文章。",
"manual_migration_explanation2": "把在其他浏览器中保存的书签、历史记录和密码带到 Firefox 吧。",

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

@ -8,7 +8,7 @@
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:unpack>false</em:unpack>
<em:version>2017.09.22.1389-2ee94db4</em:version>
<em:version>2017.09.27.1211-43262ffa</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>

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

@ -160,7 +160,7 @@ this.HighlightsFeed = class HighlightsFeed {
break;
case at.MIGRATION_COMPLETED:
case at.PLACES_HISTORY_CLEARED:
case at.PLACES_LINK_DELETED:
case at.PLACES_LINKS_DELETED:
case at.PLACES_LINK_BLOCKED:
this.fetchHighlights(true);
break;

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

@ -42,11 +42,24 @@ class HistoryObserver extends Observer {
* @param {obj} uri A URI object representing the link's url
* {str} uri.spec The URI as a string
*/
onDeleteURI(uri) {
this.dispatch({
type: at.PLACES_LINK_DELETED,
data: {url: uri.spec}
});
async onDeleteURI(uri) {
// Add to an existing array of links if we haven't dispatched yet
const {spec} = uri;
if (this._deletedLinks) {
this._deletedLinks.push(spec);
} else {
// Store an array of synchronously deleted links
this._deletedLinks = [spec];
// Only dispatch a single action when we've gotten all deleted urls
await Promise.resolve().then(() => {
this.dispatch({
type: at.PLACES_LINKS_DELETED,
data: this._deletedLinks
});
delete this._deletedLinks;
});
}
}
/**

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

@ -8,6 +8,9 @@ const {utils: Cu} = Components;
const {actionCreators: ac, actionTypes: at} = Cu.import("resource://activity-stream/common/Actions.jsm", {});
const {Prefs} = Cu.import("resource://activity-stream/lib/ActivityStreamPrefs.jsm", {});
const {PrerenderData} = Cu.import("resource://activity-stream/common/PrerenderData.jsm", {});
Cu.import("resource://gre/modules/Services.jsm");
const ONBOARDING_FINISHED_PREF = "browser.onboarding.notification.finished";
this.PrefsFeed = class PrefsFeed {
constructor(prefMap) {
@ -27,11 +30,30 @@ this.PrefsFeed = class PrefsFeed {
}
}
_initOnboardingPref() {
const snippetsEnabled = this._prefs.get("feeds.snippets");
if (!snippetsEnabled) {
this.setOnboardingDisabledDefault(true);
}
}
setOnboardingDisabledDefault(value) {
const branch = Services.prefs.getDefaultBranch("");
branch.setBoolPref(ONBOARDING_FINISHED_PREF, value);
}
onPrefChanged(name, value) {
if (this._prefMap.has(name)) {
this.store.dispatch(ac.BroadcastToContent({type: at.PREF_CHANGED, data: {name, value}}));
}
this._checkPrerender(name);
if (name === "feeds.snippets") {
// If snippets are disabled, onboarding notifications should also be
// disabled because they look like snippets.
this.setOnboardingDisabledDefault(!value);
}
}
init() {
@ -47,6 +69,7 @@ this.PrefsFeed = class PrefsFeed {
this.store.dispatch(ac.BroadcastToContent({type: at.PREFS_INITIAL_VALUES, data: values}));
this._setPrerenderPref();
this._initOnboardingPref();
}
removeListeners() {
this._prefs.ignoreBranch(this);
@ -62,6 +85,9 @@ this.PrefsFeed = class PrefsFeed {
case at.SET_PREF:
this._prefs.set(action.data.name, action.data.value);
break;
case at.DISABLE_ONBOARDING:
this.setOnboardingDisabledDefault(true);
break;
}
}
};

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

@ -17,8 +17,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "ProfileAge",
// Url to fetch snippets, in the urlFormatter service format.
const SNIPPETS_URL_PREF = "browser.aboutHomeSnippets.updateUrl";
const TELEMETRY_PREF = "datareporting.healthreport.uploadEnabled";
const ONBOARDING_FINISHED_PREF = "browser.onboarding.notification.finished";
const FXA_USERNAME_PREF = "services.sync.username";
const ONBOARDING_FINISHED_PREF = "browser.onboarding.notification.finished";
// Prefix for any target matching a search engine.
const TARGET_SEARCHENGINE_PREFIX = "searchEngine-";

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

@ -21,6 +21,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator");
const ACTIVITY_STREAM_ID = "activity-stream";
const ACTIVITY_STREAM_ENDPOINT_PREF = "browser.newtabpage.activity-stream.telemetry.ping.endpoint";
// This is a mapping table between the user preferences and its encoding code
@ -160,12 +161,10 @@ this.TelemetryFeed = class TelemetryFeed {
* Lazily initialize PingCentre to send pings
*/
get pingCentre() {
const ACTIVITY_STREAM_ID = "activity-stream";
Object.defineProperty(this, "pingCentre",
{
value: new PingCentre({
topic: ACTIVITY_STREAM_ID,
filter: ACTIVITY_STREAM_ID,
overrideEndpointPref: ACTIVITY_STREAM_ENDPOINT_PREF
})
});
@ -363,7 +362,8 @@ this.TelemetryFeed = class TelemetryFeed {
async sendEvent(event_object) {
if (this.telemetryEnabled) {
this.pingCentre.sendPing(event_object);
this.pingCentre.sendPing(event_object,
{filter: ACTIVITY_STREAM_ID});
}
}

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

@ -264,8 +264,8 @@ this.TopSitesFeed = class TopSitesFeed {
// All these actions mean we need new top sites
case at.MIGRATION_COMPLETED:
case at.PLACES_HISTORY_CLEARED:
case at.PLACES_LINK_DELETED:
case at.PLACES_LINK_BLOCKED:
case at.PLACES_LINKS_DELETED:
this.frecentCache.expire();
this.refresh();
break;

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

@ -358,13 +358,22 @@ describe("Reducers", () => {
});
it("should remove blocked and deleted urls from all rows in all sections", () => {
const blockAction = {type: at.PLACES_LINK_BLOCKED, data: {url: "www.foo.bar"}};
const deleteAction = {type: at.PLACES_LINK_DELETED, data: {url: "www.foo.bar"}};
const deleteAction = {type: at.PLACES_LINKS_DELETED, data: ["www.foo.bar"]};
const newBlockState = Sections(oldState, blockAction);
const newDeleteState = Sections(oldState, deleteAction);
newBlockState.concat(newDeleteState).forEach(section => {
assert.deepEqual(section.rows, [{url: "www.other.url"}]);
});
});
it("should remove all deleted urls", () => {
const deleteAction = {type: at.PLACES_LINKS_DELETED, data: ["www.foo.bar", "www.other.url"]};
const newState = Sections(oldState, deleteAction);
newState.forEach(section => {
assert.lengthOf(section.rows, 0);
});
});
it("should not update state for empty action.data on PLACES_BOOKMARK_ADDED", () => {
const nextState = Sections(undefined, {type: at.PLACES_BOOKMARK_ADDED});
assert.equal(nextState, INITIAL_STATE.Sections);

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

@ -296,10 +296,10 @@ describe("Highlights Feed", () => {
assert.calledOnce(feed.fetchHighlights);
assert.calledWith(feed.fetchHighlights, true);
});
it("should fetch highlights on PLACES_LINK_DELETED", async () => {
it("should fetch highlights on PLACES_LINKS_DELETED", async () => {
await feed.fetchHighlights();
feed.fetchHighlights = sinon.spy();
feed.onAction({type: at.PLACES_LINK_DELETED});
feed.onAction({type: at.PLACES_LINKS_DELETED});
assert.calledOnce(feed.fetchHighlights);
assert.calledWith(feed.fetchHighlights, true);
});

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

@ -179,9 +179,20 @@ describe("PlacesFeed", () => {
assert.property(observer, "QueryInterface");
});
describe("#onDeleteURI", () => {
it("should dispatch a PLACES_LINK_DELETED action with the right url", () => {
it("should dispatch a PLACES_LINKS_DELETED action with the right url", async() => {
await observer.onDeleteURI({spec: "foo.com"});
assert.calledWith(dispatch, {type: at.PLACES_LINKS_DELETED, data: ["foo.com"]});
});
it("should dispatch a PLACES_LINKS_DELETED action with multiple urls", async() => {
const promise = observer.onDeleteURI({spec: "bar.com"});
observer.onDeleteURI({spec: "foo.com"});
assert.calledWith(dispatch, {type: at.PLACES_LINK_DELETED, data: {url: "foo.com"}});
await promise;
const result = dispatch.firstCall.args[0].data;
assert.lengthOf(result, 2);
assert.equal(result[0], "bar.com");
assert.equal(result[1], "foo.com");
});
});
describe("#onClearHistory", () => {

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

@ -4,6 +4,7 @@ const {PrerenderData} = require("common/PrerenderData.jsm");
const {initialPrefs} = PrerenderData;
const PRERENDER_PREF_NAME = "prerender";
const ONBOARDING_FINISHED_PREF = "browser.onboarding.notification.finished";
describe("PrefsFeed", () => {
let feed;
@ -62,6 +63,44 @@ describe("PrefsFeed", () => {
assert.calledWith(feed._prefs.set, PRERENDER_PREF_NAME, false);
});
});
describe("Onboarding", () => {
let sandbox;
let defaultBranch;
beforeEach(() => {
sandbox = sinon.sandbox.create();
defaultBranch = {setBoolPref: sandbox.stub()};
sandbox.stub(global.Services.prefs, "getDefaultBranch").returns(defaultBranch);
});
afterEach(() => {
sandbox.restore();
});
it("should set ONBOARDING_FINISHED_PREF to true if prefs.feeds.snippets if false", () => {
FAKE_PREFS.set("feeds.snippets", false);
feed.onAction({type: at.INIT});
assert.calledWith(defaultBranch.setBoolPref, ONBOARDING_FINISHED_PREF, true);
});
it("should not set ONBOARDING_FINISHED_PREF if prefs.feeds.snippets is true", () => {
FAKE_PREFS.set("feeds.snippets", true);
feed.onAction({type: at.INIT});
assert.notCalled(defaultBranch.setBoolPref);
});
it("should set ONBOARDING_FINISHED_PREF to true if the feeds.snippets pref changes to false", () => {
feed.onPrefChanged("feeds.snippets", false);
assert.calledWith(defaultBranch.setBoolPref, ONBOARDING_FINISHED_PREF, true);
});
it("should set ONBOARDING_FINISHED_PREF to false if the feeds.snippets pref changes to true", () => {
feed.onPrefChanged("feeds.snippets", true);
assert.calledWith(defaultBranch.setBoolPref, ONBOARDING_FINISHED_PREF, false);
});
it("should not set ONBOARDING_FINISHED_PREF if an unrelated pref changes", () => {
feed.onPrefChanged("foo", true);
assert.notCalled(defaultBranch.setBoolPref);
});
it("should set ONBOARDING_FINISHED_PREF to true if a DISABLE_ONBOARDING action was received", () => {
feed.onAction({type: at.DISABLE_ONBOARDING});
assert.calledWith(defaultBranch.setBoolPref, ONBOARDING_FINISHED_PREF, true);
});
});
describe("onPrefChanged prerendering", () => {
it("should not change the prerender pref if the pref is not included in invalidatingPrefs", () => {
feed.onPrefChanged("foo123", true);

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

@ -507,9 +507,9 @@ describe("Top Sites Feed", () => {
assert.calledOnce(feed.refresh);
assert.equal(feed.refresh.firstCall.args[0], null);
});
it("should call refresh without a target on PLACES_LINK_DELETED action", async () => {
it("should call refresh without a target on PLACES_LINKS_DELETED action", async () => {
sinon.stub(feed, "refresh");
await feed.onAction({type: at.PLACES_LINK_DELETED});
await feed.onAction({type: at.PLACES_LINKS_DELETED});
assert.calledOnce(feed.refresh);
assert.equal(feed.refresh.firstCall.args[0], null);
});

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

@ -27,6 +27,8 @@ overrider.set({
ContentSearchUIController: function() {}, // NB: This is a function/constructor
dump() {},
fetch() {},
// eslint-disable-next-line object-shorthand
Image: function() {}, // NB: This is a function/constructor
Preferences: FakePrefs,
Services: {
locale: {

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

@ -38,7 +38,6 @@ class PingCentre {
}
this._topic = options.topic;
this._filter = options.filter;
this._prefs = Services.prefs.getBranch("");
this._setPingEndpoint(options.topic, options.overrideEndpointPref);
@ -92,12 +91,12 @@ class PingCentre {
this._fhrEnabled = this._prefs.getBoolPref(prefKey);
}
_createExperimentsString(activeExperiments) {
_createExperimentsString(activeExperiments, filter) {
let experimentsString = "";
for (let experimentID in activeExperiments) {
if (!activeExperiments[experimentID] ||
!activeExperiments[experimentID].branch ||
(this._filter && !experimentID.includes(this._filter))) {
(filter && !experimentID.includes(filter))) {
continue;
}
let expString = `${experimentID}:${activeExperiments[experimentID].branch}`;
@ -106,9 +105,10 @@ class PingCentre {
return experimentsString;
}
async sendPing(data) {
async sendPing(data, options) {
let filter = options && options.filter;
let experiments = TelemetryEnvironment.getActiveExperiments();
let experimentsString = this._createExperimentsString(experiments);
let experimentsString = this._createExperimentsString(experiments, filter);
if (!this.enabled) {
return Promise.resolve();
}