mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 14:25:52 +00:00
Bug 1435419 - Add webextension actions, add/save consistency and bug fixes to Activity Stream. r=k88hudson
MozReview-Commit-ID: AXayKIY4HfZ --HG-- extra : rebase_source : 08a54c3930df122615503f407f6e42bee1070c61
This commit is contained in:
parent
b15f168038
commit
11eea41e9c
@ -146,10 +146,14 @@ function onBrowserReady() {
|
||||
if (rows <= 0) {
|
||||
Services.prefs.setBoolPref("browser.newtabpage.activity-stream.showTopSites", false);
|
||||
} else {
|
||||
// Assume we want a full row (6 sites per row)
|
||||
Services.prefs.setIntPref("browser.newtabpage.activity-stream.topSitesCount", rows * 6);
|
||||
Services.prefs.setIntPref("browser.newtabpage.activity-stream.topSitesRows", rows);
|
||||
}
|
||||
});
|
||||
|
||||
// Old activity stream topSitesCount pref showed 6 per row
|
||||
migratePref("browser.newtabpage.activity-stream.topSitesCount", count => {
|
||||
Services.prefs.setIntPref("browser.newtabpage.activity-stream.topSitesRows", Math.ceil(count / 6));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,7 +85,9 @@ for (const type of [
|
||||
"TOP_SITES_PIN",
|
||||
"TOP_SITES_UNPIN",
|
||||
"TOP_SITES_UPDATED",
|
||||
"UNINIT"
|
||||
"UNINIT",
|
||||
"WEBEXT_CLICK",
|
||||
"WEBEXT_DISMISS"
|
||||
]) {
|
||||
actionTypes[type] = type;
|
||||
}
|
||||
@ -99,7 +101,7 @@ function _RouteMessage(action, options) {
|
||||
}
|
||||
// For each of these fields, if they are passed as an option,
|
||||
// add them to the action. If they are not defined, remove them.
|
||||
["from", "to", "toTarget", "fromTarget", "skipOrigin"].forEach(o => {
|
||||
["from", "to", "toTarget", "fromTarget", "skipMain", "skipLocal"].forEach(o => {
|
||||
if (typeof options[o] !== "undefined") {
|
||||
meta[o] = options[o];
|
||||
} else if (meta[o]) {
|
||||
@ -110,23 +112,37 @@ function _RouteMessage(action, options) {
|
||||
}
|
||||
|
||||
/**
|
||||
* SendToMain - Creates a message that will be sent to the Main process.
|
||||
* AlsoToMain - Creates a message that will be dispatched locally and also sent to the Main process.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @param {object} options
|
||||
* @param {bool} skipLocal Used by OnlyToMain to skip the main reducer
|
||||
* @param {string} fromTarget The id of the content port from which the action originated. (optional)
|
||||
* @return {object} An action with added .meta properties
|
||||
*/
|
||||
function AlsoToMain(action, fromTarget, skipLocal) {
|
||||
return _RouteMessage(action, {
|
||||
from: CONTENT_MESSAGE_TYPE,
|
||||
to: MAIN_MESSAGE_TYPE,
|
||||
fromTarget,
|
||||
skipLocal
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* OnlyToMain - Creates a message that will be sent to the Main process and skip the local reducer.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @param {object} options
|
||||
* @param {string} fromTarget The id of the content port from which the action originated. (optional)
|
||||
* @return {object} An action with added .meta properties
|
||||
*/
|
||||
function SendToMain(action, fromTarget) {
|
||||
return _RouteMessage(action, {
|
||||
from: CONTENT_MESSAGE_TYPE,
|
||||
to: MAIN_MESSAGE_TYPE,
|
||||
fromTarget
|
||||
});
|
||||
function OnlyToMain(action, fromTarget) {
|
||||
return AlsoToMain(action, fromTarget, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* BroadcastToContent - Creates a message that will be sent to ALL content processes.
|
||||
* BroadcastToContent - Creates a message that will be dispatched to main and sent to ALL content processes.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @return {object} An action with added .meta properties
|
||||
@ -139,30 +155,45 @@ function BroadcastToContent(action) {
|
||||
}
|
||||
|
||||
/**
|
||||
* SendToContent - Creates a message that will be sent to a particular Content process.
|
||||
* AlsoToOneContent - Creates a message that will be will be dispatched to the main store
|
||||
* and also sent to a particular Content process.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @param {string} target The id of a content port
|
||||
* @param {bool} skipMain Used by OnlyToOneContent to skip the main process
|
||||
* @return {object} An action with added .meta properties
|
||||
*/
|
||||
function AlsoToOneContent(action, target, skipMain) {
|
||||
if (!target) {
|
||||
throw new Error("You must provide a target ID as the second parameter of AlsoToOneContent. If you want to send to all content processes, use BroadcastToContent");
|
||||
}
|
||||
return _RouteMessage(action, {
|
||||
from: MAIN_MESSAGE_TYPE,
|
||||
to: CONTENT_MESSAGE_TYPE,
|
||||
toTarget: target,
|
||||
skipMain
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* OnlyToOneContent - Creates a message that will be sent to a particular Content process
|
||||
* and skip the main reducer.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @param {string} target The id of a content port
|
||||
* @return {object} An action with added .meta properties
|
||||
*/
|
||||
function SendToContent(action, target) {
|
||||
if (!target) {
|
||||
throw new Error("You must provide a target ID as the second parameter of SendToContent. If you want to send to all content processes, use BroadcastToContent");
|
||||
}
|
||||
return _RouteMessage(action, {
|
||||
from: MAIN_MESSAGE_TYPE,
|
||||
to: CONTENT_MESSAGE_TYPE,
|
||||
toTarget: target
|
||||
});
|
||||
function OnlyToOneContent(action, target) {
|
||||
return AlsoToOneContent(action, target, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* SendToPreloaded - Creates a message that will be sent to the preloaded tab.
|
||||
* AlsoToPreloaded - Creates a message that dispatched to the main reducer and also sent to the preloaded tab.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @return {object} An action with added .meta properties
|
||||
*/
|
||||
function SendToPreloaded(action) {
|
||||
function AlsoToPreloaded(action) {
|
||||
return _RouteMessage(action, {
|
||||
from: MAIN_MESSAGE_TYPE,
|
||||
to: PRELOAD_MESSAGE_TYPE
|
||||
@ -174,10 +205,10 @@ function SendToPreloaded(action) {
|
||||
* be sent from the UI during a user session.
|
||||
*
|
||||
* @param {object} data Fields to include in the ping (source, etc.)
|
||||
* @return {object} An SendToMain action
|
||||
* @return {object} An AlsoToMain action
|
||||
*/
|
||||
function UserEvent(data) {
|
||||
return SendToMain({
|
||||
return AlsoToMain({
|
||||
type: actionTypes.TELEMETRY_USER_EVENT,
|
||||
data
|
||||
});
|
||||
@ -188,14 +219,14 @@ function UserEvent(data) {
|
||||
*
|
||||
* @param {object} data Fields to include in the ping (value, etc.)
|
||||
* @param {int} importContext (For testing) Override the import context for testing.
|
||||
* @return {object} An action. For UI code, a SendToMain action.
|
||||
* @return {object} An action. For UI code, a AlsoToMain action.
|
||||
*/
|
||||
function UndesiredEvent(data, importContext = globalImportContext) {
|
||||
const action = {
|
||||
type: actionTypes.TELEMETRY_UNDESIRED_EVENT,
|
||||
data
|
||||
};
|
||||
return importContext === UI_CODE ? SendToMain(action) : action;
|
||||
return importContext === UI_CODE ? AlsoToMain(action) : action;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,14 +234,14 @@ function UndesiredEvent(data, importContext = globalImportContext) {
|
||||
*
|
||||
* @param {object} data Fields to include in the ping (value, etc.)
|
||||
* @param {int} importContext (For testing) Override the import context for testing.
|
||||
* @return {object} An action. For UI code, a SendToMain action.
|
||||
* @return {object} An action. For UI code, a AlsoToMain action.
|
||||
*/
|
||||
function PerfEvent(data, importContext = globalImportContext) {
|
||||
const action = {
|
||||
type: actionTypes.TELEMETRY_PERFORMANCE_EVENT,
|
||||
data
|
||||
};
|
||||
return importContext === UI_CODE ? SendToMain(action) : action;
|
||||
return importContext === UI_CODE ? AlsoToMain(action) : action;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -218,19 +249,27 @@ function PerfEvent(data, importContext = globalImportContext) {
|
||||
*
|
||||
* @param {object} data Fields to include in the ping
|
||||
* @param {int} importContext (For testing) Override the import context for testing.
|
||||
* #return {object} An action. For UI code, a SendToMain action.
|
||||
* #return {object} An action. For UI code, a AlsoToMain action.
|
||||
*/
|
||||
function ImpressionStats(data, importContext = globalImportContext) {
|
||||
const action = {
|
||||
type: actionTypes.TELEMETRY_IMPRESSION_STATS,
|
||||
data
|
||||
};
|
||||
return importContext === UI_CODE ? SendToMain(action) : action;
|
||||
return importContext === UI_CODE ? AlsoToMain(action) : action;
|
||||
}
|
||||
|
||||
function SetPref(name, value, importContext = globalImportContext) {
|
||||
const action = {type: actionTypes.SET_PREF, data: {name, value}};
|
||||
return importContext === UI_CODE ? SendToMain(action) : action;
|
||||
return importContext === UI_CODE ? AlsoToMain(action) : action;
|
||||
}
|
||||
|
||||
function WebExtEvent(type, data, importContext = globalImportContext) {
|
||||
if (!data || !data.source) {
|
||||
throw new Error("WebExtEvent actions should include a property \"source\", the id of the webextension that should receive the event.");
|
||||
}
|
||||
const action = {type, data};
|
||||
return importContext === UI_CODE ? AlsoToMain(action) : action;
|
||||
}
|
||||
|
||||
this.actionTypes = actionTypes;
|
||||
@ -241,10 +280,13 @@ this.actionCreators = {
|
||||
UndesiredEvent,
|
||||
PerfEvent,
|
||||
ImpressionStats,
|
||||
SendToContent,
|
||||
SendToMain,
|
||||
SendToPreloaded,
|
||||
SetPref
|
||||
AlsoToOneContent,
|
||||
OnlyToOneContent,
|
||||
AlsoToMain,
|
||||
OnlyToMain,
|
||||
AlsoToPreloaded,
|
||||
SetPref,
|
||||
WebExtEvent
|
||||
};
|
||||
|
||||
// These are helpers to test for certain kinds of actions
|
||||
@ -264,7 +306,7 @@ this.actionUtils = {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
isSendToContent(action) {
|
||||
isSendToOneContent(action) {
|
||||
if (!action.meta) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2,9 +2,7 @@
|
||||
"use strict";
|
||||
|
||||
/* istanbul ignore if */
|
||||
// Note: normally we would just feature detect Components.utils here, but
|
||||
// unfortunately that throws an ugly warning in content if we do.
|
||||
if (typeof Window === "undefined" && typeof Components !== "undefined" && Components.utils) {
|
||||
if (typeof ChromeUtils !== "undefined") {
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ this.PrerenderData = new _PrerenderData({
|
||||
"migrationExpired": true,
|
||||
"showTopSites": true,
|
||||
"showSearch": true,
|
||||
"topSitesCount": 12,
|
||||
"topSitesRows": 2,
|
||||
"collapseTopSites": false,
|
||||
"section.highlights.collapsed": false,
|
||||
"section.topstories.collapsed": false,
|
||||
@ -67,7 +67,7 @@ this.PrerenderData = new _PrerenderData({
|
||||
validation: [
|
||||
"showTopSites",
|
||||
"showSearch",
|
||||
"topSitesCount",
|
||||
"topSitesRows",
|
||||
"collapseTopSites",
|
||||
"section.highlights.collapsed",
|
||||
"section.topstories.collapsed",
|
||||
|
@ -6,8 +6,8 @@
|
||||
const {actionTypes: at} = ChromeUtils.import("resource://activity-stream/common/Actions.jsm", {});
|
||||
const {Dedupe} = ChromeUtils.import("resource://activity-stream/common/Dedupe.jsm", {});
|
||||
|
||||
const TOP_SITES_DEFAULT_LENGTH = 6;
|
||||
const TOP_SITES_SHOWMORE_LENGTH = 12;
|
||||
const TOP_SITES_DEFAULT_ROWS = 2;
|
||||
const TOP_SITES_MAX_SITES_PER_ROW = 6;
|
||||
|
||||
const dedupe = new Dedupe(site => site && site.url);
|
||||
|
||||
@ -24,12 +24,8 @@ const INITIAL_STATE = {
|
||||
initialized: false,
|
||||
// The history (and possibly default) links
|
||||
rows: [],
|
||||
// Used in content only to dispatch action from
|
||||
// context menu to TopSitesEdit.
|
||||
editForm: {
|
||||
visible: false,
|
||||
index: -1
|
||||
}
|
||||
// Used in content only to dispatch action to TopSiteForm.
|
||||
editForm: null
|
||||
},
|
||||
Prefs: {
|
||||
initialized: false,
|
||||
@ -95,9 +91,9 @@ function TopSites(prevState = INITIAL_STATE.TopSites, action) {
|
||||
}
|
||||
return Object.assign({}, prevState, {initialized: true, rows: action.data});
|
||||
case at.TOP_SITES_EDIT:
|
||||
return Object.assign({}, prevState, {editForm: {visible: true, index: action.data.index}});
|
||||
return Object.assign({}, prevState, {editForm: {index: action.data.index}});
|
||||
case at.TOP_SITES_CANCEL_EDIT:
|
||||
return Object.assign({}, prevState, {editForm: {visible: false}});
|
||||
return Object.assign({}, prevState, {editForm: null});
|
||||
case at.SCREENSHOT_UPDATED:
|
||||
newRows = prevState.rows.map(row => {
|
||||
if (row && row.url === action.data.url) {
|
||||
@ -323,10 +319,10 @@ function PreferencesPane(prevState = INITIAL_STATE.PreferencesPane, action) {
|
||||
}
|
||||
|
||||
this.INITIAL_STATE = INITIAL_STATE;
|
||||
this.TOP_SITES_DEFAULT_LENGTH = TOP_SITES_DEFAULT_LENGTH;
|
||||
this.TOP_SITES_SHOWMORE_LENGTH = TOP_SITES_SHOWMORE_LENGTH;
|
||||
this.TOP_SITES_DEFAULT_ROWS = TOP_SITES_DEFAULT_ROWS;
|
||||
this.TOP_SITES_MAX_SITES_PER_ROW = TOP_SITES_MAX_SITES_PER_ROW;
|
||||
|
||||
this.reducers = {TopSites, App, Snippets, Prefs, Dialog, Sections, PreferencesPane};
|
||||
this.insertPinned = insertPinned;
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["reducers", "INITIAL_STATE", "insertPinned", "TOP_SITES_DEFAULT_LENGTH", "TOP_SITES_SHOWMORE_LENGTH"];
|
||||
this.EXPORTED_SYMBOLS = ["reducers", "INITIAL_STATE", "insertPinned", "TOP_SITES_DEFAULT_ROWS", "TOP_SITES_MAX_SITES_PER_ROW"];
|
||||
|
@ -106,7 +106,7 @@ const actionTypes = {};
|
||||
/* harmony export (immutable) */ __webpack_exports__["b"] = actionTypes;
|
||||
|
||||
|
||||
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", "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", "PAGE_PRERENDERED", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_CHANGED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINKS_DELETED", "PLACES_LINK_BLOCKED", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "RICH_ICON_MISSING", "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", "SETTINGS_CLOSE", "SETTINGS_OPEN", "SET_PREF", "SHOW_FIREFOX_ACCOUNTS", "SNIPPETS_BLOCKLIST_UPDATED", "SNIPPETS_DATA", "SNIPPETS_RESET", "SNIPPET_BLOCKED", "SYSTEM_TICK", "TELEMETRY_IMPRESSION_STATS", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_CANCEL_EDIT", "TOP_SITES_EDIT", "TOP_SITES_INSERT", "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", "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", "PAGE_PRERENDERED", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_CHANGED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINKS_DELETED", "PLACES_LINK_BLOCKED", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "RICH_ICON_MISSING", "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", "SETTINGS_CLOSE", "SETTINGS_OPEN", "SET_PREF", "SHOW_FIREFOX_ACCOUNTS", "SNIPPETS_BLOCKLIST_UPDATED", "SNIPPETS_DATA", "SNIPPETS_RESET", "SNIPPET_BLOCKED", "SYSTEM_TICK", "TELEMETRY_IMPRESSION_STATS", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_CANCEL_EDIT", "TOP_SITES_EDIT", "TOP_SITES_INSERT", "TOP_SITES_PIN", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "UNINIT", "WEBEXT_CLICK", "WEBEXT_DISMISS"]) {
|
||||
actionTypes[type] = type;
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ function _RouteMessage(action, options) {
|
||||
}
|
||||
// For each of these fields, if they are passed as an option,
|
||||
// add them to the action. If they are not defined, remove them.
|
||||
["from", "to", "toTarget", "fromTarget", "skipOrigin"].forEach(o => {
|
||||
["from", "to", "toTarget", "fromTarget", "skipMain", "skipLocal"].forEach(o => {
|
||||
if (typeof options[o] !== "undefined") {
|
||||
meta[o] = options[o];
|
||||
} else if (meta[o]) {
|
||||
@ -130,23 +130,37 @@ function _RouteMessage(action, options) {
|
||||
}
|
||||
|
||||
/**
|
||||
* SendToMain - Creates a message that will be sent to the Main process.
|
||||
* AlsoToMain - Creates a message that will be dispatched locally and also sent to the Main process.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @param {object} options
|
||||
* @param {bool} skipLocal Used by OnlyToMain to skip the main reducer
|
||||
* @param {string} fromTarget The id of the content port from which the action originated. (optional)
|
||||
* @return {object} An action with added .meta properties
|
||||
*/
|
||||
function AlsoToMain(action, fromTarget, skipLocal) {
|
||||
return _RouteMessage(action, {
|
||||
from: CONTENT_MESSAGE_TYPE,
|
||||
to: MAIN_MESSAGE_TYPE,
|
||||
fromTarget,
|
||||
skipLocal
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* OnlyToMain - Creates a message that will be sent to the Main process and skip the local reducer.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @param {object} options
|
||||
* @param {string} fromTarget The id of the content port from which the action originated. (optional)
|
||||
* @return {object} An action with added .meta properties
|
||||
*/
|
||||
function SendToMain(action, fromTarget) {
|
||||
return _RouteMessage(action, {
|
||||
from: CONTENT_MESSAGE_TYPE,
|
||||
to: MAIN_MESSAGE_TYPE,
|
||||
fromTarget
|
||||
});
|
||||
function OnlyToMain(action, fromTarget) {
|
||||
return AlsoToMain(action, fromTarget, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* BroadcastToContent - Creates a message that will be sent to ALL content processes.
|
||||
* BroadcastToContent - Creates a message that will be dispatched to main and sent to ALL content processes.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @return {object} An action with added .meta properties
|
||||
@ -159,30 +173,45 @@ function BroadcastToContent(action) {
|
||||
}
|
||||
|
||||
/**
|
||||
* SendToContent - Creates a message that will be sent to a particular Content process.
|
||||
* AlsoToOneContent - Creates a message that will be will be dispatched to the main store
|
||||
* and also sent to a particular Content process.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @param {string} target The id of a content port
|
||||
* @param {bool} skipMain Used by OnlyToOneContent to skip the main process
|
||||
* @return {object} An action with added .meta properties
|
||||
*/
|
||||
function AlsoToOneContent(action, target, skipMain) {
|
||||
if (!target) {
|
||||
throw new Error("You must provide a target ID as the second parameter of AlsoToOneContent. If you want to send to all content processes, use BroadcastToContent");
|
||||
}
|
||||
return _RouteMessage(action, {
|
||||
from: MAIN_MESSAGE_TYPE,
|
||||
to: CONTENT_MESSAGE_TYPE,
|
||||
toTarget: target,
|
||||
skipMain
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* OnlyToOneContent - Creates a message that will be sent to a particular Content process
|
||||
* and skip the main reducer.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @param {string} target The id of a content port
|
||||
* @return {object} An action with added .meta properties
|
||||
*/
|
||||
function SendToContent(action, target) {
|
||||
if (!target) {
|
||||
throw new Error("You must provide a target ID as the second parameter of SendToContent. If you want to send to all content processes, use BroadcastToContent");
|
||||
}
|
||||
return _RouteMessage(action, {
|
||||
from: MAIN_MESSAGE_TYPE,
|
||||
to: CONTENT_MESSAGE_TYPE,
|
||||
toTarget: target
|
||||
});
|
||||
function OnlyToOneContent(action, target) {
|
||||
return AlsoToOneContent(action, target, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* SendToPreloaded - Creates a message that will be sent to the preloaded tab.
|
||||
* AlsoToPreloaded - Creates a message that dispatched to the main reducer and also sent to the preloaded tab.
|
||||
*
|
||||
* @param {object} action Any redux action (required)
|
||||
* @return {object} An action with added .meta properties
|
||||
*/
|
||||
function SendToPreloaded(action) {
|
||||
function AlsoToPreloaded(action) {
|
||||
return _RouteMessage(action, {
|
||||
from: MAIN_MESSAGE_TYPE,
|
||||
to: PRELOAD_MESSAGE_TYPE
|
||||
@ -194,10 +223,10 @@ function SendToPreloaded(action) {
|
||||
* be sent from the UI during a user session.
|
||||
*
|
||||
* @param {object} data Fields to include in the ping (source, etc.)
|
||||
* @return {object} An SendToMain action
|
||||
* @return {object} An AlsoToMain action
|
||||
*/
|
||||
function UserEvent(data) {
|
||||
return SendToMain({
|
||||
return AlsoToMain({
|
||||
type: actionTypes.TELEMETRY_USER_EVENT,
|
||||
data
|
||||
});
|
||||
@ -208,14 +237,14 @@ function UserEvent(data) {
|
||||
*
|
||||
* @param {object} data Fields to include in the ping (value, etc.)
|
||||
* @param {int} importContext (For testing) Override the import context for testing.
|
||||
* @return {object} An action. For UI code, a SendToMain action.
|
||||
* @return {object} An action. For UI code, a AlsoToMain action.
|
||||
*/
|
||||
function UndesiredEvent(data, importContext = globalImportContext) {
|
||||
const action = {
|
||||
type: actionTypes.TELEMETRY_UNDESIRED_EVENT,
|
||||
data
|
||||
};
|
||||
return importContext === UI_CODE ? SendToMain(action) : action;
|
||||
return importContext === UI_CODE ? AlsoToMain(action) : action;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -223,14 +252,14 @@ function UndesiredEvent(data, importContext = globalImportContext) {
|
||||
*
|
||||
* @param {object} data Fields to include in the ping (value, etc.)
|
||||
* @param {int} importContext (For testing) Override the import context for testing.
|
||||
* @return {object} An action. For UI code, a SendToMain action.
|
||||
* @return {object} An action. For UI code, a AlsoToMain action.
|
||||
*/
|
||||
function PerfEvent(data, importContext = globalImportContext) {
|
||||
const action = {
|
||||
type: actionTypes.TELEMETRY_PERFORMANCE_EVENT,
|
||||
data
|
||||
};
|
||||
return importContext === UI_CODE ? SendToMain(action) : action;
|
||||
return importContext === UI_CODE ? AlsoToMain(action) : action;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -238,19 +267,27 @@ function PerfEvent(data, importContext = globalImportContext) {
|
||||
*
|
||||
* @param {object} data Fields to include in the ping
|
||||
* @param {int} importContext (For testing) Override the import context for testing.
|
||||
* #return {object} An action. For UI code, a SendToMain action.
|
||||
* #return {object} An action. For UI code, a AlsoToMain action.
|
||||
*/
|
||||
function ImpressionStats(data, importContext = globalImportContext) {
|
||||
const action = {
|
||||
type: actionTypes.TELEMETRY_IMPRESSION_STATS,
|
||||
data
|
||||
};
|
||||
return importContext === UI_CODE ? SendToMain(action) : action;
|
||||
return importContext === UI_CODE ? AlsoToMain(action) : action;
|
||||
}
|
||||
|
||||
function SetPref(name, value, importContext = globalImportContext) {
|
||||
const action = { type: actionTypes.SET_PREF, data: { name, value } };
|
||||
return importContext === UI_CODE ? SendToMain(action) : action;
|
||||
return importContext === UI_CODE ? AlsoToMain(action) : action;
|
||||
}
|
||||
|
||||
function WebExtEvent(type, data, importContext = globalImportContext) {
|
||||
if (!data || !data.source) {
|
||||
throw new Error("WebExtEvent actions should include a property \"source\", the id of the webextension that should receive the event.");
|
||||
}
|
||||
const action = { type, data };
|
||||
return importContext === UI_CODE ? AlsoToMain(action) : action;
|
||||
}
|
||||
|
||||
var actionCreators = {
|
||||
@ -259,10 +296,13 @@ var actionCreators = {
|
||||
UndesiredEvent,
|
||||
PerfEvent,
|
||||
ImpressionStats,
|
||||
SendToContent,
|
||||
SendToMain,
|
||||
SendToPreloaded,
|
||||
SetPref
|
||||
AlsoToOneContent,
|
||||
OnlyToOneContent,
|
||||
AlsoToMain,
|
||||
OnlyToMain,
|
||||
AlsoToPreloaded,
|
||||
SetPref,
|
||||
WebExtEvent
|
||||
};
|
||||
|
||||
// These are helpers to test for certain kinds of actions
|
||||
@ -283,7 +323,7 @@ var actionUtils = {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
isSendToContent(action) {
|
||||
isSendToOneContent(action) {
|
||||
if (!action.meta) {
|
||||
return false;
|
||||
}
|
||||
@ -399,7 +439,7 @@ class Dedupe {
|
||||
}
|
||||
// CONCATENATED MODULE: ./system-addon/common/Reducers.jsm
|
||||
/* unused harmony export insertPinned */
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return reducers; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return reducers; });
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -407,11 +447,11 @@ class Dedupe {
|
||||
|
||||
|
||||
|
||||
const TOP_SITES_DEFAULT_LENGTH = 6;
|
||||
/* harmony export (immutable) */ __webpack_exports__["a"] = TOP_SITES_DEFAULT_LENGTH;
|
||||
const TOP_SITES_DEFAULT_ROWS = 2;
|
||||
/* unused harmony export TOP_SITES_DEFAULT_ROWS */
|
||||
|
||||
const TOP_SITES_SHOWMORE_LENGTH = 12;
|
||||
/* harmony export (immutable) */ __webpack_exports__["b"] = TOP_SITES_SHOWMORE_LENGTH;
|
||||
const TOP_SITES_MAX_SITES_PER_ROW = 6;
|
||||
/* harmony export (immutable) */ __webpack_exports__["a"] = TOP_SITES_MAX_SITES_PER_ROW;
|
||||
|
||||
|
||||
|
||||
@ -430,12 +470,8 @@ const INITIAL_STATE = {
|
||||
initialized: false,
|
||||
// The history (and possibly default) links
|
||||
rows: [],
|
||||
// Used in content only to dispatch action from
|
||||
// context menu to TopSitesEdit.
|
||||
editForm: {
|
||||
visible: false,
|
||||
index: -1
|
||||
}
|
||||
// Used in content only to dispatch action to TopSiteForm.
|
||||
editForm: null
|
||||
},
|
||||
Prefs: {
|
||||
initialized: false,
|
||||
@ -507,9 +543,9 @@ function TopSites(prevState = INITIAL_STATE.TopSites, action) {
|
||||
}
|
||||
return Object.assign({}, prevState, { initialized: true, rows: action.data });
|
||||
case Actions["b" /* actionTypes */].TOP_SITES_EDIT:
|
||||
return Object.assign({}, prevState, { editForm: { visible: true, index: action.data.index } });
|
||||
return Object.assign({}, prevState, { editForm: { index: action.data.index } });
|
||||
case Actions["b" /* actionTypes */].TOP_SITES_CANCEL_EDIT:
|
||||
return Object.assign({}, prevState, { editForm: { visible: false } });
|
||||
return Object.assign({}, prevState, { editForm: null });
|
||||
case Actions["b" /* actionTypes */].SCREENSHOT_UPDATED:
|
||||
newRows = prevState.rows.map(row => {
|
||||
if (row && row.url === action.data.url) {
|
||||
@ -853,7 +889,7 @@ const LinkMenuOptions = {
|
||||
RemoveBookmark: site => ({
|
||||
id: "menu_action_remove_bookmark",
|
||||
icon: "bookmark-added",
|
||||
action: Actions["a" /* actionCreators */].SendToMain({
|
||||
action: Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].DELETE_BOOKMARK_BY_ID,
|
||||
data: site.bookmarkGuid
|
||||
}),
|
||||
@ -862,7 +898,7 @@ const LinkMenuOptions = {
|
||||
AddBookmark: site => ({
|
||||
id: "menu_action_bookmark",
|
||||
icon: "bookmark-hollow",
|
||||
action: Actions["a" /* actionCreators */].SendToMain({
|
||||
action: Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].BOOKMARK_URL,
|
||||
data: { url: site.url, title: site.title, type: site.type }
|
||||
}),
|
||||
@ -871,7 +907,7 @@ const LinkMenuOptions = {
|
||||
OpenInNewWindow: site => ({
|
||||
id: "menu_action_open_new_window",
|
||||
icon: "new-window",
|
||||
action: Actions["a" /* actionCreators */].SendToMain({
|
||||
action: Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].OPEN_NEW_WINDOW,
|
||||
data: { url: site.url, referrer: site.referrer }
|
||||
}),
|
||||
@ -880,7 +916,7 @@ const LinkMenuOptions = {
|
||||
OpenInPrivateWindow: site => ({
|
||||
id: "menu_action_open_private_window",
|
||||
icon: "new-window-private",
|
||||
action: Actions["a" /* actionCreators */].SendToMain({
|
||||
action: Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].OPEN_PRIVATE_WINDOW,
|
||||
data: { url: site.url, referrer: site.referrer }
|
||||
}),
|
||||
@ -889,7 +925,7 @@ const LinkMenuOptions = {
|
||||
BlockUrl: (site, index, eventSource) => ({
|
||||
id: "menu_action_dismiss",
|
||||
icon: "dismiss",
|
||||
action: Actions["a" /* actionCreators */].SendToMain({
|
||||
action: Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].BLOCK_URL,
|
||||
data: site.url
|
||||
}),
|
||||
@ -900,13 +936,26 @@ const LinkMenuOptions = {
|
||||
}),
|
||||
userEvent: "BLOCK"
|
||||
}),
|
||||
|
||||
// This is an option for web extentions which will result in remove items from
|
||||
// memory and notify the web extenion, rather than using the built-in block list.
|
||||
WebExtDismiss: (site, index, eventSource) => ({
|
||||
id: "menu_action_webext_dismiss",
|
||||
string_id: "menu_action_dismiss",
|
||||
icon: "dismiss",
|
||||
action: Actions["a" /* actionCreators */].WebExtEvent(Actions["b" /* actionTypes */].WEBEXT_DISMISS, {
|
||||
source: eventSource,
|
||||
url: site.url,
|
||||
action_position: index
|
||||
})
|
||||
}),
|
||||
DeleteUrl: site => ({
|
||||
id: "menu_action_delete",
|
||||
icon: "delete",
|
||||
action: {
|
||||
type: Actions["b" /* actionTypes */].DIALOG_OPEN,
|
||||
data: {
|
||||
onConfirm: [Actions["a" /* actionCreators */].SendToMain({ type: Actions["b" /* actionTypes */].DELETE_HISTORY_URL, data: { url: site.url, forceBlock: site.bookmarkGuid } }), Actions["a" /* actionCreators */].UserEvent({ event: "DELETE" })],
|
||||
onConfirm: [Actions["a" /* actionCreators */].AlsoToMain({ type: Actions["b" /* actionTypes */].DELETE_HISTORY_URL, data: { url: site.url, forceBlock: site.bookmarkGuid } }), Actions["a" /* actionCreators */].UserEvent({ event: "DELETE" })],
|
||||
body_string_id: ["confirm_history_delete_p1", "confirm_history_delete_notice_p2"],
|
||||
confirm_button_string_id: "menu_action_delete",
|
||||
cancel_button_string_id: "topsites_form_cancel_button",
|
||||
@ -918,7 +967,7 @@ const LinkMenuOptions = {
|
||||
PinTopSite: (site, index) => ({
|
||||
id: "menu_action_pin",
|
||||
icon: "pin",
|
||||
action: Actions["a" /* actionCreators */].SendToMain({
|
||||
action: Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].TOP_SITES_PIN,
|
||||
data: { site: { url: site.url }, index }
|
||||
}),
|
||||
@ -927,7 +976,7 @@ const LinkMenuOptions = {
|
||||
UnpinTopSite: site => ({
|
||||
id: "menu_action_unpin",
|
||||
icon: "unpin",
|
||||
action: Actions["a" /* actionCreators */].SendToMain({
|
||||
action: Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].TOP_SITES_UNPIN,
|
||||
data: { site: { url: site.url } }
|
||||
}),
|
||||
@ -936,7 +985,7 @@ const LinkMenuOptions = {
|
||||
SaveToPocket: (site, index, eventSource) => ({
|
||||
id: "menu_action_save_to_pocket",
|
||||
icon: "pocket",
|
||||
action: Actions["a" /* actionCreators */].SendToMain({
|
||||
action: Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].SAVE_TO_POCKET,
|
||||
data: { site: { url: site.url, title: site.title } }
|
||||
}),
|
||||
@ -976,9 +1025,9 @@ class LinkMenu__LinkMenu extends external__React__default.a.PureComponent {
|
||||
const propOptions = !site.isDefault ? props.options : DEFAULT_SITE_MENU_OPTIONS;
|
||||
|
||||
const options = propOptions.map(o => LinkMenuOptions[o](site, index, source)).map(option => {
|
||||
const { action, impression, id, type, userEvent } = option;
|
||||
const { action, impression, id, string_id, type, userEvent } = option;
|
||||
if (!type && id) {
|
||||
option.label = props.intl.formatMessage(option);
|
||||
option.label = props.intl.formatMessage({ id: string_id || id });
|
||||
option.onClick = () => {
|
||||
props.dispatch(action);
|
||||
if (userEvent) {
|
||||
@ -1454,7 +1503,7 @@ class ComponentPerfTimer extends __WEBPACK_IMPORTED_MODULE_2_react___default.a.C
|
||||
const firstRenderKey = `${this.props.id}_first_render_ts`;
|
||||
// value has to be Int32.
|
||||
const value = parseInt(this.perfSvc.getMostRecentAbsMarkStartByName(dataReadyKey) - this.perfSvc.getMostRecentAbsMarkStartByName(firstRenderKey), 10);
|
||||
this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({
|
||||
this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].OnlyToMain({
|
||||
type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SAVE_SESSION_PERF_DATA,
|
||||
// highlights_data_late_by_ms, topsites_data_late_by_ms.
|
||||
data: { [`${this.props.id}_data_late_by_ms`]: value }
|
||||
@ -1479,7 +1528,7 @@ class ComponentPerfTimer extends __WEBPACK_IMPORTED_MODULE_2_react___default.a.C
|
||||
const data = {};
|
||||
data[key] = this.perfSvc.getMostRecentAbsMarkStartByName(key);
|
||||
|
||||
this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({
|
||||
this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].OnlyToMain({
|
||||
type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SAVE_SESSION_PERF_DATA,
|
||||
data
|
||||
}));
|
||||
@ -1512,10 +1561,8 @@ class ComponentPerfTimer extends __WEBPACK_IMPORTED_MODULE_2_react___default.a.C
|
||||
|
||||
|
||||
/* istanbul ignore if */
|
||||
// Note: normally we would just feature detect Components.utils here, but
|
||||
// unfortunately that throws an ugly warning in content if we do.
|
||||
|
||||
if (typeof Window === "undefined" && typeof Components !== "undefined" && Components.utils) {
|
||||
if (typeof ChromeUtils !== "undefined") {
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
}
|
||||
|
||||
@ -1665,7 +1712,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||||
|
||||
|
||||
|
||||
const store = Object(__WEBPACK_IMPORTED_MODULE_4_content_src_lib_init_store__["a" /* initStore */])(__WEBPACK_IMPORTED_MODULE_8_common_Reducers_jsm__["c" /* reducers */], global.gActivityStreamPrerenderedState);
|
||||
const store = Object(__WEBPACK_IMPORTED_MODULE_4_content_src_lib_init_store__["a" /* initStore */])(__WEBPACK_IMPORTED_MODULE_8_common_Reducers_jsm__["b" /* reducers */], global.gActivityStreamPrerenderedState);
|
||||
|
||||
new __WEBPACK_IMPORTED_MODULE_3_content_src_lib_detect_user_session_start__["a" /* DetectUserSessionStart */](store).sendEventOrAddListener();
|
||||
|
||||
@ -1673,7 +1720,7 @@ new __WEBPACK_IMPORTED_MODULE_3_content_src_lib_detect_user_session_start__["a"
|
||||
// to request state rehydration (see Base.jsx). If we are NOT in a prerendered state,
|
||||
// we can request it immedately.
|
||||
if (!global.gActivityStreamPrerenderedState) {
|
||||
store.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].NEW_TAB_STATE_REQUEST }));
|
||||
store.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].AlsoToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].NEW_TAB_STATE_REQUEST }));
|
||||
}
|
||||
|
||||
__WEBPACK_IMPORTED_MODULE_7_react_dom___default.a.render(__WEBPACK_IMPORTED_MODULE_6_react___default.a.createElement(
|
||||
@ -1755,17 +1802,17 @@ class SnippetsMap extends Map {
|
||||
const { blockList } = this;
|
||||
if (!blockList.includes(id)) {
|
||||
blockList.push(id);
|
||||
this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SNIPPETS_BLOCKLIST_UPDATED, data: blockList }));
|
||||
this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].AlsoToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SNIPPETS_BLOCKLIST_UPDATED, data: blockList }));
|
||||
await this.set("blockList", blockList);
|
||||
}
|
||||
}
|
||||
|
||||
disableOnboarding() {
|
||||
this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].DISABLE_ONBOARDING }));
|
||||
this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].AlsoToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].DISABLE_ONBOARDING }));
|
||||
}
|
||||
|
||||
showFirefoxAccounts() {
|
||||
this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SHOW_FIREFOX_ACCOUNTS }));
|
||||
this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].AlsoToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SHOW_FIREFOX_ACCOUNTS }));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2101,7 +2148,7 @@ var external__React__default = /*#__PURE__*/__webpack_require__.n(external__Reac
|
||||
* data: {
|
||||
* // Any sort of data needed to be passed around by actions.
|
||||
* payload: site.url,
|
||||
* // Primary button SendToMain action.
|
||||
* // Primary button AlsoToMain action.
|
||||
* action: "DELETE_HISTORY_URL",
|
||||
* // Primary button USerEvent action.
|
||||
* userEvent: "DELETE",
|
||||
@ -2205,12 +2252,12 @@ class ManualMigration__ManualMigration extends external__React__default.a.PureCo
|
||||
}
|
||||
|
||||
onLaunchTour() {
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({ type: Actions["b" /* actionTypes */].MIGRATION_START }));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].AlsoToMain({ type: Actions["b" /* actionTypes */].MIGRATION_START }));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({ event: Actions["b" /* actionTypes */].MIGRATION_START }));
|
||||
}
|
||||
|
||||
onCancelTour() {
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({ type: Actions["b" /* actionTypes */].MIGRATION_CANCEL }));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].AlsoToMain({ type: Actions["b" /* actionTypes */].MIGRATION_CANCEL }));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({ event: Actions["b" /* actionTypes */].MIGRATION_CANCEL }));
|
||||
}
|
||||
|
||||
@ -2243,16 +2290,12 @@ class ManualMigration__ManualMigration extends external__React__default.a.PureCo
|
||||
}
|
||||
|
||||
const ManualMigration = Object(external__ReactRedux_["connect"])()(ManualMigration__ManualMigration);
|
||||
// EXTERNAL MODULE: ./system-addon/common/Reducers.jsm + 1 modules
|
||||
var Reducers = __webpack_require__(5);
|
||||
|
||||
// CONCATENATED MODULE: ./system-addon/content-src/components/PreferencesPane/PreferencesPane.jsx
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const getFormattedMessage = message => typeof message === "string" ? external__React__default.a.createElement(
|
||||
"span",
|
||||
null,
|
||||
@ -2314,8 +2357,8 @@ class PreferencesPane__PreferencesPane extends external__React__default.a.PureCo
|
||||
|
||||
handlePrefChange({ target: { name, checked } }) {
|
||||
let value = checked;
|
||||
if (name === "topSitesCount") {
|
||||
value = checked ? Reducers["b" /* TOP_SITES_SHOWMORE_LENGTH */] : Reducers["a" /* TOP_SITES_DEFAULT_LENGTH */];
|
||||
if (name === "topSitesRows") {
|
||||
value = checked ? 2 : 1;
|
||||
}
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SetPref(name, value));
|
||||
}
|
||||
@ -2323,7 +2366,7 @@ class PreferencesPane__PreferencesPane extends external__React__default.a.PureCo
|
||||
handleSectionChange({ target }) {
|
||||
const id = target.name;
|
||||
const type = target.checked ? Actions["b" /* actionTypes */].SECTION_ENABLE : Actions["b" /* actionTypes */].SECTION_DISABLE;
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({ type, data: id }));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].AlsoToMain({ type, data: id }));
|
||||
}
|
||||
|
||||
togglePane() {
|
||||
@ -2394,9 +2437,9 @@ class PreferencesPane__PreferencesPane extends external__React__default.a.PureCo
|
||||
descString: { id: "settings_pane_topsites_body" } },
|
||||
external__React__default.a.createElement(PreferencesInput, {
|
||||
className: "showMoreTopSites",
|
||||
prefName: "topSitesCount",
|
||||
prefName: "topSitesRows",
|
||||
disabled: !prefs.showTopSites,
|
||||
value: prefs.topSitesCount !== Reducers["a" /* TOP_SITES_DEFAULT_LENGTH */],
|
||||
value: prefs.topSitesRows === 2,
|
||||
onChange: this.handlePrefChange,
|
||||
titleString: { id: "settings_pane_topsites_options_showmore" },
|
||||
labelClassName: "icon icon-topsites" })
|
||||
@ -2499,7 +2542,7 @@ var PrerenderData = new _PrerenderData({
|
||||
"migrationExpired": true,
|
||||
"showTopSites": true,
|
||||
"showSearch": true,
|
||||
"topSitesCount": 12,
|
||||
"topSitesRows": 2,
|
||||
"collapseTopSites": false,
|
||||
"section.highlights.collapsed": false,
|
||||
"section.topstories.collapsed": false,
|
||||
@ -2512,7 +2555,7 @@ var PrerenderData = new _PrerenderData({
|
||||
// too different for the prerendered version to be used. Unfortunately, this
|
||||
// will result in users who have modified some of their preferences not being
|
||||
// able to get the benefits of prerendering.
|
||||
validation: ["showTopSites", "showSearch", "topSitesCount", "collapseTopSites", "section.highlights.collapsed", "section.topstories.collapsed",
|
||||
validation: ["showTopSites", "showSearch", "topSitesRows", "collapseTopSites", "section.highlights.collapsed", "section.topstories.collapsed",
|
||||
// This means if either of these are set to their default values,
|
||||
// prerendering can be used.
|
||||
{ oneOf: ["feeds.section.topstories", "feeds.section.highlights"] }],
|
||||
@ -2651,6 +2694,9 @@ var CollapsibleSection = __webpack_require__(7);
|
||||
// EXTERNAL MODULE: ./system-addon/content-src/components/ComponentPerfTimer/ComponentPerfTimer.jsx
|
||||
var ComponentPerfTimer = __webpack_require__(8);
|
||||
|
||||
// EXTERNAL MODULE: ./system-addon/common/Reducers.jsm + 1 modules
|
||||
var Reducers = __webpack_require__(5);
|
||||
|
||||
// CONCATENATED MODULE: ./system-addon/content-src/components/TopSites/TopSiteForm.jsx
|
||||
|
||||
|
||||
@ -2660,16 +2706,16 @@ var ComponentPerfTimer = __webpack_require__(8);
|
||||
class TopSiteForm_TopSiteForm extends external__React__default.a.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const { site } = props;
|
||||
this.state = {
|
||||
label: props.label || "",
|
||||
url: props.url || "",
|
||||
label: site ? site.label || site.hostname : "",
|
||||
url: site ? site.url : "",
|
||||
validationError: false
|
||||
};
|
||||
this.onLabelChange = this.onLabelChange.bind(this);
|
||||
this.onUrlChange = this.onUrlChange.bind(this);
|
||||
this.onCancelButtonClick = this.onCancelButtonClick.bind(this);
|
||||
this.onAddButtonClick = this.onAddButtonClick.bind(this);
|
||||
this.onSaveButtonClick = this.onSaveButtonClick.bind(this);
|
||||
this.onDoneButtonClick = this.onDoneButtonClick.bind(this);
|
||||
this.onUrlInputMount = this.onUrlInputMount.bind(this);
|
||||
}
|
||||
|
||||
@ -2688,41 +2734,26 @@ class TopSiteForm_TopSiteForm extends external__React__default.a.PureComponent {
|
||||
this.props.onClose();
|
||||
}
|
||||
|
||||
onAddButtonClick(ev) {
|
||||
onDoneButtonClick(ev) {
|
||||
ev.preventDefault();
|
||||
if (this.validateForm()) {
|
||||
let site = { url: this.cleanUrl() };
|
||||
if (this.state.label !== "") {
|
||||
site.label = this.state.label;
|
||||
}
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
|
||||
type: Actions["b" /* actionTypes */].TOP_SITES_INSERT,
|
||||
data: { site }
|
||||
}));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
|
||||
source: TOP_SITES_SOURCE,
|
||||
event: "TOP_SITES_ADD"
|
||||
}));
|
||||
this.props.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
onSaveButtonClick(ev) {
|
||||
ev.preventDefault();
|
||||
if (this.validateForm()) {
|
||||
let site = { url: this.cleanUrl() };
|
||||
const site = { url: this.cleanUrl() };
|
||||
const { index } = this.props;
|
||||
if (this.state.label !== "") {
|
||||
site.label = this.state.label;
|
||||
}
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
|
||||
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].TOP_SITES_PIN,
|
||||
data: { site, index: this.props.index }
|
||||
data: { site, index }
|
||||
}));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
|
||||
source: TOP_SITES_SOURCE,
|
||||
event: "TOP_SITES_EDIT",
|
||||
action_position: this.props.index
|
||||
action_position: index
|
||||
}));
|
||||
|
||||
this.props.onClose();
|
||||
}
|
||||
}
|
||||
@ -2766,6 +2797,9 @@ class TopSiteForm_TopSiteForm extends external__React__default.a.PureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
// For UI purposes, editing without an existing link is "add"
|
||||
const showAsAdd = !this.props.site;
|
||||
|
||||
return external__React__default.a.createElement(
|
||||
"form",
|
||||
{ className: "topsite-form" },
|
||||
@ -2778,7 +2812,7 @@ class TopSiteForm_TopSiteForm extends external__React__default.a.PureComponent {
|
||||
external__React__default.a.createElement(
|
||||
"h3",
|
||||
{ className: "section-title" },
|
||||
external__React__default.a.createElement(external__ReactIntl_["FormattedMessage"], { id: this.props.editMode ? "topsites_form_edit_header" : "topsites_form_add_header" })
|
||||
external__React__default.a.createElement(external__ReactIntl_["FormattedMessage"], { id: showAsAdd ? "topsites_form_add_header" : "topsites_form_edit_header" })
|
||||
),
|
||||
external__React__default.a.createElement(
|
||||
"div",
|
||||
@ -2814,15 +2848,10 @@ class TopSiteForm_TopSiteForm extends external__React__default.a.PureComponent {
|
||||
{ className: "cancel", type: "button", onClick: this.onCancelButtonClick },
|
||||
external__React__default.a.createElement(external__ReactIntl_["FormattedMessage"], { id: "topsites_form_cancel_button" })
|
||||
),
|
||||
this.props.editMode && external__React__default.a.createElement(
|
||||
external__React__default.a.createElement(
|
||||
"button",
|
||||
{ className: "done save", type: "submit", onClick: this.onSaveButtonClick },
|
||||
external__React__default.a.createElement(external__ReactIntl_["FormattedMessage"], { id: "topsites_form_save_button" })
|
||||
),
|
||||
!this.props.editMode && external__React__default.a.createElement(
|
||||
"button",
|
||||
{ className: "done add", type: "submit", onClick: this.onAddButtonClick },
|
||||
external__React__default.a.createElement(external__ReactIntl_["FormattedMessage"], { id: "topsites_form_add_button" })
|
||||
{ className: "done", type: "submit", onClick: this.onDoneButtonClick },
|
||||
external__React__default.a.createElement(external__ReactIntl_["FormattedMessage"], { id: showAsAdd ? "topsites_form_add_button" : "topsites_form_save_button" })
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -2830,10 +2859,8 @@ class TopSiteForm_TopSiteForm extends external__React__default.a.PureComponent {
|
||||
}
|
||||
|
||||
TopSiteForm_TopSiteForm.defaultProps = {
|
||||
label: "",
|
||||
url: "",
|
||||
index: 0,
|
||||
editMode: false // by default we are in "Add New Top Site" mode
|
||||
TopSite: null,
|
||||
index: -1
|
||||
};
|
||||
// EXTERNAL MODULE: ./system-addon/content-src/components/LinkMenu/LinkMenu.jsx + 2 modules
|
||||
var LinkMenu = __webpack_require__(6);
|
||||
@ -2847,6 +2874,7 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < argument
|
||||
|
||||
|
||||
|
||||
|
||||
class TopSite_TopSiteLink extends external__React__default.a.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -3051,11 +3079,6 @@ class TopSite_TopSitePlaceholder extends external__React__default.a.PureComponen
|
||||
}
|
||||
|
||||
onEditButtonClick() {
|
||||
if (this.props.onEdit) {
|
||||
this.props.onEdit(this.props.index);
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.dispatch({ type: Actions["b" /* actionTypes */].TOP_SITES_EDIT, data: { index: this.props.index } });
|
||||
}
|
||||
|
||||
@ -3135,7 +3158,7 @@ class TopSite__TopSiteList extends external__React__default.a.PureComponent {
|
||||
case "drop":
|
||||
if (index !== this.state.draggedIndex) {
|
||||
this.dropped = true;
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].TOP_SITES_INSERT,
|
||||
data: { site: { url: this.state.draggedSite.url, label: this.state.draggedTitle }, index, draggedFromIndex: this.state.draggedIndex }
|
||||
}));
|
||||
@ -3148,7 +3171,7 @@ class TopSite__TopSiteList extends external__React__default.a.PureComponent {
|
||||
_getTopSites() {
|
||||
// Make a copy of the sites to truncate or extend to desired length
|
||||
let topSites = this.props.TopSites.rows.slice();
|
||||
topSites.length = this.props.TopSitesCount;
|
||||
topSites.length = this.props.TopSitesRows * Reducers["a" /* TOP_SITES_MAX_SITES_PER_ROW */];
|
||||
return topSites;
|
||||
}
|
||||
|
||||
@ -3218,11 +3241,8 @@ class TopSite__TopSiteList extends external__React__default.a.PureComponent {
|
||||
key: link ? link.url : holeIndex++,
|
||||
index: i
|
||||
};
|
||||
topSitesUI.push(!link ? external__React__default.a.createElement(TopSite_TopSitePlaceholder, _extends({
|
||||
onEdit: props.onEdit
|
||||
}, slotProps, commonProps)) : external__React__default.a.createElement(TopSite_TopSite, _extends({
|
||||
topSitesUI.push(!link ? external__React__default.a.createElement(TopSite_TopSitePlaceholder, _extends({}, slotProps, commonProps)) : external__React__default.a.createElement(TopSite_TopSite, _extends({
|
||||
link: link,
|
||||
onEdit: props.onEdit,
|
||||
activeIndex: this.state.activeIndex,
|
||||
onActivate: this.onActivate
|
||||
}, slotProps, commonProps)));
|
||||
@ -3247,6 +3267,7 @@ const TopSiteList = Object(external__ReactIntl_["injectIntl"])(TopSite__TopSiteL
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Iterates through TopSites and counts types of images.
|
||||
* @param acc Accumulator for reducer.
|
||||
@ -3279,17 +3300,8 @@ function countTopSitesIconsTypes(topSites) {
|
||||
}
|
||||
|
||||
class TopSites__TopSites extends external__React__default.a.PureComponent {
|
||||
static get DEFAULT_STATE() {
|
||||
return {
|
||||
showAddForm: false,
|
||||
showEditForm: false,
|
||||
editIndex: -1 // Index of top site being edited
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = TopSites__TopSites.DEFAULT_STATE;
|
||||
this.onAddButtonClick = this.onAddButtonClick.bind(this);
|
||||
this.onFormClose = this.onFormClose.bind(this);
|
||||
}
|
||||
@ -3302,7 +3314,7 @@ class TopSites__TopSites extends external__React__default.a.PureComponent {
|
||||
const topSitesIconsStats = countTopSitesIconsTypes(topSites);
|
||||
const topSitesPinned = topSites.filter(site => !!site.isPinned).length;
|
||||
// Dispatch telemetry event with the count of TopSites images types.
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].SAVE_SESSION_PERF_DATA,
|
||||
data: { topsites_icon_stats: topSitesIconsStats, topsites_pinned: topSitesPinned }
|
||||
}));
|
||||
@ -3312,7 +3324,7 @@ class TopSites__TopSites extends external__React__default.a.PureComponent {
|
||||
* Return the TopSites to display based on prefs.
|
||||
*/
|
||||
_getTopSites() {
|
||||
return this.props.TopSites.rows.slice(0, this.props.TopSitesCount);
|
||||
return this.props.TopSites.rows.slice(0, this.props.TopSitesRows * Reducers["a" /* TOP_SITES_MAX_SITES_PER_ROW */]);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
@ -3324,15 +3336,15 @@ class TopSites__TopSites extends external__React__default.a.PureComponent {
|
||||
}
|
||||
|
||||
onAddButtonClick() {
|
||||
this.setState({ showAddForm: true });
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
|
||||
source: TOP_SITES_SOURCE,
|
||||
event: "TOP_SITES_ADD_FORM_OPEN"
|
||||
}));
|
||||
// Negative index will prepend the TopSite at the beginning of the list
|
||||
this.props.dispatch({ type: Actions["b" /* actionTypes */].TOP_SITES_EDIT, data: { index: -1 } });
|
||||
}
|
||||
|
||||
onFormClose() {
|
||||
this.setState(TopSites__TopSites.DEFAULT_STATE);
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
|
||||
source: TOP_SITES_SOURCE,
|
||||
event: "TOP_SITES_EDIT_CLOSE"
|
||||
@ -3346,21 +3358,15 @@ class TopSites__TopSites extends external__React__default.a.PureComponent {
|
||||
header: { id: "settings_pane_topsites_header" },
|
||||
body: { id: "settings_pane_topsites_body" }
|
||||
};
|
||||
const { showAddForm } = this.state;
|
||||
const { editForm } = this.props.TopSites;
|
||||
const showEditForm = editForm && editForm.visible || this.state.showEditForm;
|
||||
let { editIndex } = this.state;
|
||||
if (editIndex < 0 && editForm) {
|
||||
editIndex = editForm.index;
|
||||
}
|
||||
const editSite = this.props.TopSites.rows[editIndex] || {};
|
||||
const { editForm } = props.TopSites;
|
||||
|
||||
return external__React__default.a.createElement(
|
||||
ComponentPerfTimer["a" /* ComponentPerfTimer */],
|
||||
{ id: "topsites", initialized: props.TopSites.initialized, dispatch: props.dispatch },
|
||||
external__React__default.a.createElement(
|
||||
CollapsibleSection["a" /* CollapsibleSection */],
|
||||
{ className: "top-sites", icon: "topsites", title: external__React__default.a.createElement(external__ReactIntl_["FormattedMessage"], { id: "header_top_sites" }), infoOption: infoOption, prefName: "collapseTopSites", Prefs: props.Prefs, dispatch: props.dispatch },
|
||||
external__React__default.a.createElement(TopSiteList, { TopSites: props.TopSites, TopSitesCount: props.TopSitesCount, dispatch: props.dispatch, intl: props.intl }),
|
||||
external__React__default.a.createElement(TopSiteList, { TopSites: props.TopSites, TopSitesRows: props.TopSitesRows, dispatch: props.dispatch, intl: props.intl }),
|
||||
external__React__default.a.createElement(
|
||||
"div",
|
||||
{ className: "edit-topsites-wrapper" },
|
||||
@ -3376,17 +3382,7 @@ class TopSites__TopSites extends external__React__default.a.PureComponent {
|
||||
external__React__default.a.createElement(external__ReactIntl_["FormattedMessage"], { id: "edit_topsites_add_button" })
|
||||
)
|
||||
),
|
||||
showAddForm && external__React__default.a.createElement(
|
||||
"div",
|
||||
{ className: "edit-topsites" },
|
||||
external__React__default.a.createElement("div", { className: "modal-overlay", onClick: this.onFormClose }),
|
||||
external__React__default.a.createElement(
|
||||
"div",
|
||||
{ className: "modal" },
|
||||
external__React__default.a.createElement(TopSiteForm_TopSiteForm, { onClose: this.onFormClose, dispatch: this.props.dispatch, intl: this.props.intl })
|
||||
)
|
||||
),
|
||||
showEditForm && external__React__default.a.createElement(
|
||||
editForm && external__React__default.a.createElement(
|
||||
"div",
|
||||
{ className: "edit-topsites" },
|
||||
external__React__default.a.createElement("div", { className: "modal-overlay", onClick: this.onFormClose }),
|
||||
@ -3394,10 +3390,8 @@ class TopSites__TopSites extends external__React__default.a.PureComponent {
|
||||
"div",
|
||||
{ className: "modal" },
|
||||
external__React__default.a.createElement(TopSiteForm_TopSiteForm, {
|
||||
label: editSite.label || editSite.hostname || "",
|
||||
url: editSite.url || "",
|
||||
index: editIndex,
|
||||
editMode: true,
|
||||
site: props.TopSites.rows[editForm.index],
|
||||
index: editForm.index,
|
||||
onClose: this.onFormClose,
|
||||
dispatch: this.props.dispatch,
|
||||
intl: this.props.intl })
|
||||
@ -3412,7 +3406,7 @@ class TopSites__TopSites extends external__React__default.a.PureComponent {
|
||||
const TopSites = Object(external__ReactRedux_["connect"])(state => ({
|
||||
TopSites: state.TopSites,
|
||||
Prefs: state.Prefs,
|
||||
TopSitesCount: state.Prefs.values.topSitesCount
|
||||
TopSitesRows: state.Prefs.values.topSitesRows
|
||||
}))(Object(external__ReactIntl_["injectIntl"])(TopSites__TopSites));
|
||||
// CONCATENATED MODULE: ./system-addon/content-src/components/Base/Base.jsx
|
||||
|
||||
@ -3446,8 +3440,8 @@ class Base__Base extends external__React__default.a.PureComponent {
|
||||
// prerendered DOM to be unmounted. Otherwise, NEW_TAB_STATE_REQUEST is
|
||||
// dispatched right after the store is ready.
|
||||
if (this.props.isPrerendered) {
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({ type: Actions["b" /* actionTypes */].NEW_TAB_STATE_REQUEST }));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({ type: Actions["b" /* actionTypes */].PAGE_PRERENDERED }));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].AlsoToMain({ type: Actions["b" /* actionTypes */].NEW_TAB_STATE_REQUEST }));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].AlsoToMain({ type: Actions["b" /* actionTypes */].PAGE_PRERENDERED }));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3460,7 +3454,7 @@ class Base__Base extends external__React__default.a.PureComponent {
|
||||
// have rendered that data.
|
||||
sendNewTabRehydrated(App) {
|
||||
if (App && App.initialized && !this.renderNotified) {
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({ type: Actions["b" /* actionTypes */].NEW_TAB_REHYDRATED, data: {} }));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].AlsoToMain({ type: Actions["b" /* actionTypes */].NEW_TAB_REHYDRATED, data: {} }));
|
||||
this.renderNotified = true;
|
||||
}
|
||||
}
|
||||
@ -3697,7 +3691,7 @@ class Section extends __WEBPACK_IMPORTED_MODULE_6_react___default.a.PureComponen
|
||||
"ul",
|
||||
{ className: "section-list", style: { padding: 0 } },
|
||||
realRows.map((link, index) => link && __WEBPACK_IMPORTED_MODULE_6_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_0_content_src_components_Card_Card__["a" /* Card */], { key: index, index: index, dispatch: dispatch, link: link, contextMenuOptions: contextMenuOptions,
|
||||
eventSource: eventSource, shouldSendImpressionStats: this.props.shouldSendImpressionStats })),
|
||||
eventSource: eventSource, shouldSendImpressionStats: this.props.shouldSendImpressionStats, isWebExtension: this.props.isWebExtension })),
|
||||
placeholders > 0 && [...new Array(placeholders)].map((_, i) => __WEBPACK_IMPORTED_MODULE_6_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_0_content_src_components_Card_Card__["b" /* PlaceholderCard */], { key: i }))
|
||||
),
|
||||
shouldShowEmptyState && __WEBPACK_IMPORTED_MODULE_6_react___default.a.createElement(
|
||||
@ -3864,21 +3858,31 @@ class Card_Card extends external__React__default.a.PureComponent {
|
||||
onLinkClick(event) {
|
||||
event.preventDefault();
|
||||
const { altKey, button, ctrlKey, metaKey, shiftKey } = event;
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].AlsoToMain({
|
||||
type: Actions["b" /* actionTypes */].OPEN_LINK,
|
||||
data: Object.assign(this.props.link, { event: { altKey, button, ctrlKey, metaKey, shiftKey } })
|
||||
}));
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
|
||||
event: "CLICK",
|
||||
source: this.props.eventSource,
|
||||
action_position: this.props.index
|
||||
}));
|
||||
if (this.props.shouldSendImpressionStats) {
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].ImpressionStats({
|
||||
|
||||
if (this.props.isWebExtension) {
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].WebExtEvent(Actions["b" /* actionTypes */].WEBEXT_CLICK, {
|
||||
source: this.props.eventSource,
|
||||
click: 0,
|
||||
tiles: [{ id: this.props.link.guid, pos: this.props.index }]
|
||||
url: this.props.link.url,
|
||||
action_position: this.props.index
|
||||
}));
|
||||
} else {
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
|
||||
event: "CLICK",
|
||||
source: this.props.eventSource,
|
||||
action_position: this.props.index
|
||||
}));
|
||||
|
||||
if (this.props.shouldSendImpressionStats) {
|
||||
this.props.dispatch(Actions["a" /* actionCreators */].ImpressionStats({
|
||||
source: this.props.eventSource,
|
||||
click: 0,
|
||||
tiles: [{ id: this.props.link.guid, pos: this.props.index }]
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4101,7 +4105,7 @@ class DetectUserSessionStart {
|
||||
try {
|
||||
let visibility_event_rcvd_ts = this._perfService.getMostRecentAbsMarkStartByName("visibility_event_rcvd_ts");
|
||||
|
||||
this._store.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({
|
||||
this._store.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].AlsoToMain({
|
||||
type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SAVE_SESSION_PERF_DATA,
|
||||
data: { visibility_event_rcvd_ts }
|
||||
}));
|
||||
@ -4183,10 +4187,13 @@ function mergeStateReducer(mainReducer) {
|
||||
* messageMiddleware - Middleware that looks for SentToMain type actions, and sends them if necessary
|
||||
*/
|
||||
const messageMiddleware = store => next => action => {
|
||||
const skipLocal = action.meta && action.meta.skipLocal;
|
||||
if (__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["c" /* actionUtils */].isSendToMain(action)) {
|
||||
sendAsyncMessage(OUTGOING_MESSAGE_NAME, action);
|
||||
}
|
||||
next(action);
|
||||
if (!skipLocal) {
|
||||
next(action);
|
||||
}
|
||||
};
|
||||
|
||||
const rehydrationMiddleware = store => next => action => {
|
||||
@ -4209,10 +4216,10 @@ const rehydrationMiddleware = store => next => action => {
|
||||
|
||||
// If init happened after our request was made, we need to re-request
|
||||
if (store._didRequestInitialState && action.type === __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].INIT) {
|
||||
return next(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].NEW_TAB_STATE_REQUEST }));
|
||||
return next(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].AlsoToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].NEW_TAB_STATE_REQUEST }));
|
||||
}
|
||||
|
||||
if (__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["c" /* actionUtils */].isBroadcastToContent(action) || __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["c" /* actionUtils */].isSendToContent(action) || __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["c" /* actionUtils */].isSendToPreloaded(action)) {
|
||||
if (__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["c" /* actionUtils */].isBroadcastToContent(action) || __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["c" /* actionUtils */].isSendToOneContent(action) || __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["c" /* actionUtils */].isSendToPreloaded(action)) {
|
||||
// Note that actions received before didRehydrate will not be dispatched
|
||||
// because this could negatively affect preloading and the the state
|
||||
// will be replaced by rehydration anyway.
|
||||
|
@ -8,7 +8,7 @@
|
||||
<em:type>2</em:type>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:unpack>false</em:unpack>
|
||||
<em:version>2018.01.30.1052-2ec746e0</em:version>
|
||||
<em:version>2018.02.05.1095-9be4c3c6</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>
|
||||
|
@ -106,9 +106,9 @@ const PREFS_CONFIG = new Map([
|
||||
title: "Collapse the Top Sites section",
|
||||
value: false
|
||||
}],
|
||||
["topSitesCount", {
|
||||
title: "Number of Top Sites to display",
|
||||
value: 12
|
||||
["topSitesRows", {
|
||||
title: "Number of rows of Top Sites to display",
|
||||
value: 2
|
||||
}],
|
||||
["telemetry", {
|
||||
title: "Enable system error and usage data collection",
|
||||
|
@ -26,7 +26,7 @@ this.ActivityStreamMessageChannel = class ActivityStreamMessageChannel {
|
||||
/**
|
||||
* ActivityStreamMessageChannel - This module connects a Redux store to a RemotePageManager in Firefox.
|
||||
* Call .createChannel to start the connection, and .destroyChannel to destroy it.
|
||||
* You should use the BroadcastToContent, SendToContent, and SendToMain action creators
|
||||
* You should use the BroadcastToContent, AlsoToOneContent, and AlsoToMain action creators
|
||||
* in common/Actions.jsm to help you create actions that will be automatically routed
|
||||
* to the correct location.
|
||||
*
|
||||
@ -51,7 +51,7 @@ this.ActivityStreamMessageChannel = class ActivityStreamMessageChannel {
|
||||
}
|
||||
|
||||
/**
|
||||
* middleware - Redux middleware that looks for SendToContent and BroadcastToContent type
|
||||
* middleware - Redux middleware that looks for AlsoToOneContent and BroadcastToContent type
|
||||
* actions, and sends them out.
|
||||
*
|
||||
* @param {object} store A redux store
|
||||
@ -64,7 +64,7 @@ this.ActivityStreamMessageChannel = class ActivityStreamMessageChannel {
|
||||
next(action);
|
||||
return;
|
||||
}
|
||||
if (au.isSendToContent(action)) {
|
||||
if (au.isSendToOneContent(action)) {
|
||||
this.send(action);
|
||||
} else if (au.isBroadcastToContent(action)) {
|
||||
this.broadcast(action);
|
||||
@ -85,7 +85,7 @@ this.ActivityStreamMessageChannel = class ActivityStreamMessageChannel {
|
||||
* @param {string} targetId The portID of the port that sent the message
|
||||
*/
|
||||
onActionFromContent(action, targetId) {
|
||||
this.dispatch(ac.SendToMain(action, targetId));
|
||||
this.dispatch(ac.AlsoToMain(action, targetId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10,7 +10,7 @@ const {actionTypes: at} = ChromeUtils.import("resource://activity-stream/common/
|
||||
|
||||
const {shortURL} = ChromeUtils.import("resource://activity-stream/lib/ShortURL.jsm", {});
|
||||
const {SectionsManager} = ChromeUtils.import("resource://activity-stream/lib/SectionsManager.jsm", {});
|
||||
const {TOP_SITES_SHOWMORE_LENGTH} = ChromeUtils.import("resource://activity-stream/common/Reducers.jsm", {});
|
||||
const {TOP_SITES_DEFAULT_ROWS, TOP_SITES_MAX_SITES_PER_ROW} = ChromeUtils.import("resource://activity-stream/common/Reducers.jsm", {});
|
||||
const {Dedupe} = ChromeUtils.import("resource://activity-stream/common/Dedupe.jsm", {});
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "filterAdult",
|
||||
@ -25,7 +25,7 @@ ChromeUtils.defineModuleGetter(this, "PageThumbs",
|
||||
"resource://gre/modules/PageThumbs.jsm");
|
||||
|
||||
const HIGHLIGHTS_MAX_LENGTH = 9;
|
||||
const MANY_EXTRA_LENGTH = HIGHLIGHTS_MAX_LENGTH * 5 + TOP_SITES_SHOWMORE_LENGTH;
|
||||
const MANY_EXTRA_LENGTH = HIGHLIGHTS_MAX_LENGTH * 5 + TOP_SITES_DEFAULT_ROWS * TOP_SITES_MAX_SITES_PER_ROW;
|
||||
const SECTION_ID = "highlights";
|
||||
|
||||
this.HighlightsFeed = class HighlightsFeed {
|
||||
|
@ -23,7 +23,7 @@ this.NewTabInit = class NewTabInit {
|
||||
}
|
||||
|
||||
const action = {type: at.NEW_TAB_INITIAL_STATE, data: this.store.getState()};
|
||||
this.store.dispatch(ac.SendToContent(action, target));
|
||||
this.store.dispatch(ac.AlsoToOneContent(action, target));
|
||||
|
||||
// Remember that this early tab has already gotten a rehydration response in
|
||||
// case it thought we lost its initial REQUEST and asked again
|
||||
|
@ -247,7 +247,10 @@ class PlacesFeed {
|
||||
* Open a link in a desired destination defaulting to action's event.
|
||||
*/
|
||||
openLink(action, where = "", isPrivate = false) {
|
||||
const params = {private: isPrivate};
|
||||
const params = {
|
||||
private: isPrivate,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({})
|
||||
};
|
||||
|
||||
// Always include the referrer (even for http links) if we have one
|
||||
const {event, referrer} = action.data;
|
||||
|
@ -82,7 +82,7 @@ const BUILT_IN_SECTIONS = {
|
||||
};
|
||||
|
||||
const SectionsManager = {
|
||||
ACTIONS_TO_PROXY: ["SYSTEM_TICK", "NEW_TAB_LOAD"],
|
||||
ACTIONS_TO_PROXY: ["WEBEXT_CLICK", "WEBEXT_DISMISS"],
|
||||
CONTEXT_MENU_PREFS: {"SaveToPocket": "extensions.pocket.enabled"},
|
||||
initialized: false,
|
||||
sections: new Map(),
|
||||
@ -223,6 +223,13 @@ const SectionsManager = {
|
||||
this.emit(this.UPDATE_SECTION_CARD, id, url, options, shouldBroadcast);
|
||||
}
|
||||
},
|
||||
removeSectionCard(sectionId, url) {
|
||||
if (!this.sections.has(sectionId)) {
|
||||
return;
|
||||
}
|
||||
const rows = this.sections.get(sectionId).rows.filter(row => row.url !== url);
|
||||
this.updateSection(sectionId, {rows}, true);
|
||||
},
|
||||
onceInitialized(callback) {
|
||||
if (this.initialized) {
|
||||
callback();
|
||||
@ -294,14 +301,14 @@ class SectionsFeed {
|
||||
onUpdateSection(event, id, options, shouldBroadcast = false) {
|
||||
if (options) {
|
||||
const action = {type: at.SECTION_UPDATE, data: Object.assign(options, {id})};
|
||||
this.store.dispatch(shouldBroadcast ? ac.BroadcastToContent(action) : ac.SendToPreloaded(action));
|
||||
this.store.dispatch(shouldBroadcast ? ac.BroadcastToContent(action) : ac.AlsoToPreloaded(action));
|
||||
}
|
||||
}
|
||||
|
||||
onUpdateSectionCard(event, id, url, options, shouldBroadcast = false) {
|
||||
if (options) {
|
||||
const action = {type: at.SECTION_UPDATE_CARD, data: {id, url, options}};
|
||||
this.store.dispatch(shouldBroadcast ? ac.BroadcastToContent(action) : ac.SendToPreloaded(action));
|
||||
this.store.dispatch(shouldBroadcast ? ac.BroadcastToContent(action) : ac.AlsoToPreloaded(action));
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,6 +334,11 @@ class SectionsFeed {
|
||||
case at.PLACES_BOOKMARK_ADDED:
|
||||
SectionsManager.updateBookmarkMetadata(action.data);
|
||||
break;
|
||||
case at.WEBEXT_DISMISS:
|
||||
if (action.data) {
|
||||
SectionsManager.removeSectionCard(action.data.source, action.data.url);
|
||||
}
|
||||
break;
|
||||
case at.SECTION_DISABLE:
|
||||
SectionsManager.disableSection(action.data);
|
||||
break;
|
||||
|
@ -8,7 +8,7 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const {actionCreators: ac, actionTypes: at} = ChromeUtils.import("resource://activity-stream/common/Actions.jsm", {});
|
||||
const {TippyTopProvider} = ChromeUtils.import("resource://activity-stream/lib/TippyTopProvider.jsm", {});
|
||||
const {insertPinned, TOP_SITES_SHOWMORE_LENGTH} = ChromeUtils.import("resource://activity-stream/common/Reducers.jsm", {});
|
||||
const {insertPinned, TOP_SITES_DEFAULT_ROWS, TOP_SITES_MAX_SITES_PER_ROW} = ChromeUtils.import("resource://activity-stream/common/Reducers.jsm", {});
|
||||
const {Dedupe} = ChromeUtils.import("resource://activity-stream/common/Dedupe.jsm", {});
|
||||
const {shortURL} = ChromeUtils.import("resource://activity-stream/lib/ShortURL.jsm", {});
|
||||
|
||||
@ -74,9 +74,8 @@ this.TopSitesFeed = class TopSitesFeed {
|
||||
}
|
||||
|
||||
async getLinksWithDefaults(action) {
|
||||
// Get at least SHOWMORE amount so toggling between 1 and 2 rows has sites
|
||||
const numItems = Math.max(this.store.getState().Prefs.values.topSitesCount,
|
||||
TOP_SITES_SHOWMORE_LENGTH);
|
||||
// Get at least TOP_SITES_DEFAULT_ROWS (2) amount so toggling between 1 and 2 rows has sites
|
||||
const numItems = Math.max(this.store.getState().Prefs.values.topSitesRows, TOP_SITES_DEFAULT_ROWS) * TOP_SITES_MAX_SITES_PER_ROW;
|
||||
const frecent = (await this.frecentCache.request({
|
||||
numItems,
|
||||
topsiteFrecency: FRECENCY_THRESHOLD
|
||||
@ -159,7 +158,7 @@ this.TopSitesFeed = class TopSitesFeed {
|
||||
this.store.dispatch(ac.BroadcastToContent(newAction));
|
||||
} else {
|
||||
// Don't broadcast only update the state and update the preloaded tab.
|
||||
this.store.dispatch(ac.SendToPreloaded(newAction));
|
||||
this.store.dispatch(ac.AlsoToPreloaded(newAction));
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,8 +225,13 @@ this.TopSitesFeed = class TopSitesFeed {
|
||||
*/
|
||||
pin(action) {
|
||||
const {site, index} = action.data;
|
||||
this._pinSiteAt(site, index);
|
||||
this._broadcastPinnedSitesUpdated();
|
||||
// If valid index provided, pin at that position
|
||||
if (index >= 0) {
|
||||
this._pinSiteAt(site, index);
|
||||
this._broadcastPinnedSitesUpdated();
|
||||
} else {
|
||||
this.insert(action);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,7 +250,7 @@ this.TopSitesFeed = class TopSitesFeed {
|
||||
// Don't insert any pins past the end of the visible top sites. Otherwise,
|
||||
// we can end up with a bunch of pinned sites that can never be unpinned again
|
||||
// from the UI.
|
||||
const {topSitesCount} = this.store.getState().Prefs.values;
|
||||
const topSitesCount = this.store.getState().Prefs.values.topSitesRows * TOP_SITES_MAX_SITES_PER_ROW;
|
||||
if (index >= topSitesCount) {
|
||||
return;
|
||||
}
|
||||
@ -285,11 +289,17 @@ this.TopSitesFeed = class TopSitesFeed {
|
||||
* Handle an insert (drop/add) action of a site.
|
||||
*/
|
||||
insert(action) {
|
||||
let {index} = action.data;
|
||||
// Treat invalid pin index values (e.g., -1, undefined) as insert in the first position
|
||||
if (!(index > 0)) {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
// Inserting a top site pins it in the specified slot, pushing over any link already
|
||||
// pinned in the slot (unless it's the last slot, then it replaces).
|
||||
this._insertPin(
|
||||
action.data.site, action.data.index || 0,
|
||||
action.data.draggedFromIndex !== undefined ? action.data.draggedFromIndex : this.store.getState().Prefs.values.topSitesCount);
|
||||
action.data.site, index,
|
||||
action.data.draggedFromIndex !== undefined ? action.data.draggedFromIndex : this.store.getState().Prefs.values.topSitesRows * TOP_SITES_MAX_SITES_PER_ROW);
|
||||
this._broadcastPinnedSitesUpdated();
|
||||
}
|
||||
|
||||
|
@ -317,8 +317,8 @@ this.TopStoriesFeed = class TopStoriesFeed {
|
||||
rows.splice(2, 0, spocs[0]);
|
||||
|
||||
// Send a content update to the target tab
|
||||
const action = {type: at.SECTION_UPDATE, meta: {skipMain: true}, data: Object.assign({rows}, {id: SECTION_ID})};
|
||||
this.store.dispatch(ac.SendToContent(action, target));
|
||||
const action = {type: at.SECTION_UPDATE, data: Object.assign({rows}, {id: SECTION_ID})};
|
||||
this.store.dispatch(ac.OnlyToOneContent(action, target));
|
||||
return false;
|
||||
};
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Lami tam obedo {provider}",
|
||||
"header_bookmarks_placeholder": "Pud i pee ki alamabuk.",
|
||||
"header_stories_from": "ki bot",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Yab jami ayera pi {title}",
|
||||
"type_label_visited": "Kilimo",
|
||||
"type_label_bookmarked": "Kiketo alamabuk",
|
||||
"type_label_synced": "Kiribo ki i nyonyo mukene",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Yub kakube man",
|
||||
"edit_topsites_dismiss_button": "Kwer kakube man",
|
||||
"edit_topsites_add_button": "Medi",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Med Kakube maloyo",
|
||||
"topsites_form_add_header": "Kakube maloyo manyen",
|
||||
"topsites_form_edit_header": "Yub Kakube maloyo",
|
||||
"topsites_form_title_placeholder": "Ket wiye",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "{provider} məsləhət görür",
|
||||
"header_bookmarks_placeholder": "Hələlik heç əlfəcininiz yoxdur.",
|
||||
"header_stories_from": "qaynaq:",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "{title} üçün kontekst menyusunu aç",
|
||||
"type_label_visited": "Ziyarət edilib",
|
||||
"type_label_bookmarked": "Əlfəcinlənib",
|
||||
"type_label_synced": "Digər cihazdan sync edilib",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Bu saytı düzəlt",
|
||||
"edit_topsites_dismiss_button": "Bu saytı çıxart",
|
||||
"edit_topsites_add_button": "Əlavə et",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Qabaqcıl sayt əlavə et",
|
||||
"topsites_form_add_header": "Yeni Qabaqcıl Saytlar",
|
||||
"topsites_form_edit_header": "Qabaqcıl Saytları Dəyişdir",
|
||||
"topsites_form_title_placeholder": "Başlıq daxil et",
|
||||
|
File diff suppressed because one or more lines are too long
@ -2,7 +2,7 @@
|
||||
window.gActivityStreamStrings = {
|
||||
"newtab_page_title": "Нов раздел",
|
||||
"default_label_loading": "Зареждане…",
|
||||
"header_top_sites": "Най-посещавани",
|
||||
"header_top_sites": "Често посещавани",
|
||||
"header_stories": "Популярни",
|
||||
"header_highlights": "Акценти",
|
||||
"header_visit_again": "Посещаване",
|
||||
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Препоръчано от {provider}",
|
||||
"header_bookmarks_placeholder": "Все още нямате отметки.",
|
||||
"header_stories_from": "от",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Отваряне на контекстуалното меню на {title}",
|
||||
"type_label_visited": "Посетена",
|
||||
"type_label_bookmarked": "Отметната",
|
||||
"type_label_synced": "Синхронизирана от друго устройство",
|
||||
@ -54,8 +54,8 @@ window.gActivityStreamStrings = {
|
||||
"settings_pane_body2": "Изберете какво да виждате на тази страница.",
|
||||
"settings_pane_search_header": "Търсене",
|
||||
"settings_pane_search_body": "Търсете в мрежата от нов раздел.",
|
||||
"settings_pane_topsites_header": "Най-посещавани",
|
||||
"settings_pane_topsites_body": "Достъп до сайтовете, които посещавате най-често.",
|
||||
"settings_pane_topsites_header": "Често посещавани",
|
||||
"settings_pane_topsites_body": "Достъп до страниците, които посещавате най-често.",
|
||||
"settings_pane_topsites_options_showmore": "Показване на два реда",
|
||||
"settings_pane_bookmarks_header": "Последни отметки",
|
||||
"settings_pane_bookmarks_body": "Всички нови отметки на едно място.",
|
||||
@ -70,7 +70,7 @@ window.gActivityStreamStrings = {
|
||||
"settings_pane_done_button": "Готово",
|
||||
"settings_pane_topstories_options_sponsored": "Показване на платени статии",
|
||||
"edit_topsites_button_text": "Редактиране",
|
||||
"edit_topsites_button_label": "Настройки на най-посещаваните",
|
||||
"edit_topsites_button_label": "Настройки на често посещаваните",
|
||||
"edit_topsites_showmore_button": "Повече",
|
||||
"edit_topsites_showless_button": "По-малко",
|
||||
"edit_topsites_done_button": "Готово",
|
||||
@ -79,9 +79,9 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Редактиране",
|
||||
"edit_topsites_dismiss_button": "Изтриване",
|
||||
"edit_topsites_add_button": "Добавяне",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"topsites_form_add_header": "Нов най-посещаван сайт",
|
||||
"topsites_form_edit_header": "Редактиране на най-посещаван сайт",
|
||||
"edit_topsites_add_button_tooltip": "Добавяне към често посещаваните страници",
|
||||
"topsites_form_add_header": "Нов често посещавана страница",
|
||||
"topsites_form_edit_header": "Редактиране на често посещавана страница",
|
||||
"topsites_form_title_placeholder": "Заглавие",
|
||||
"topsites_form_url_placeholder": "Адрес",
|
||||
"topsites_form_add_button": "Добавяне",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "{provider} দ্বারা সুপারিশকৃত",
|
||||
"header_bookmarks_placeholder": "এখনও কোন বুকমার্ক নেই।",
|
||||
"header_stories_from": "থেকে",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "{title} থেকে কনটেক্সট মেনু খুলুন",
|
||||
"type_label_visited": "পরিদর্শিত",
|
||||
"type_label_bookmarked": "বুকমার্ক করা হয়েছে",
|
||||
"type_label_synced": "অন্য ডিভাইস থেকে সিঙ্ক করা হয়েছে",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "সাইটটি সম্পাদনা করুন",
|
||||
"edit_topsites_dismiss_button": "সাইটটি মুছে দিন",
|
||||
"edit_topsites_add_button": "যোগ",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "টপ সাইট যোগ করুন",
|
||||
"topsites_form_add_header": "নতুন শীর্ষ সাইট",
|
||||
"topsites_form_edit_header": "শীর্ষ সাইট সম্পাদনা করুন",
|
||||
"topsites_form_title_placeholder": "নাম দিন",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "{provider} দ্বারা সুপারিশকৃত",
|
||||
"header_bookmarks_placeholder": "এখনও কোন বুকমার্ক নেই।",
|
||||
"header_stories_from": "থেকে",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "{title} থেকে কনটেক্সট মেনু খুলুন",
|
||||
"type_label_visited": "দেখা হয়েছে",
|
||||
"type_label_bookmarked": "বুকমার্ক করা হয়েছে",
|
||||
"type_label_synced": "অন্য ডিভাইস থেকে সিঙ্ক করা হয়েছে",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "সাইটটি সম্পাদনা করুন",
|
||||
"edit_topsites_dismiss_button": "সাইটটি মুছে দিন",
|
||||
"edit_topsites_add_button": "যুক্ত করুন",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "টপ সাইট যোগ করুন",
|
||||
"topsites_form_add_header": "নতুন শীর্ষ সাইট",
|
||||
"topsites_form_edit_header": "শীর্ষ সাইট সম্পাদনা করুন",
|
||||
"topsites_form_title_placeholder": "একটি শিরোনাম লিখুন",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Argymhellwyd gan {provider}",
|
||||
"header_bookmarks_placeholder": "Nid oes gennych unrhyw nodau tudalen eto.",
|
||||
"header_stories_from": "oddi wrth",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Agor dewislen cynnwys {title}",
|
||||
"type_label_visited": "Ymwelwyd",
|
||||
"type_label_bookmarked": "Nod Tudalen",
|
||||
"type_label_synced": "Cydweddwyd o ddyfais arall",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Golygu'r wefan",
|
||||
"edit_topsites_dismiss_button": "Dileu'r wefan",
|
||||
"edit_topsites_add_button": "Ychwanegu",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Ychwanegu Prif Wefan",
|
||||
"topsites_form_add_header": "Hoff Wefan Newydd",
|
||||
"topsites_form_edit_header": "Golygu'r Hoff Wefan",
|
||||
"topsites_form_title_placeholder": "Rhoi teitl",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Rekomendita de {provider}",
|
||||
"header_bookmarks_placeholder": "Vi ankoraŭ ne havas legosignojn.",
|
||||
"header_stories_from": "el",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Malfermi kuntekstan menu por {title}",
|
||||
"type_label_visited": "Vizitita",
|
||||
"type_label_bookmarked": "Kun legosigno",
|
||||
"type_label_synced": "Spegulitaj el alia aparato",
|
||||
@ -79,9 +79,9 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Redakti ĉi tiun retejon",
|
||||
"edit_topsites_dismiss_button": "Ignori ĉi tiun retejon",
|
||||
"edit_topsites_add_button": "Aldoni",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Aldoni oftan retejon",
|
||||
"topsites_form_add_header": "Nova ofta retejo",
|
||||
"topsites_form_edit_header": "Redakti ofta retejo",
|
||||
"topsites_form_edit_header": "Redakti oftan retejon",
|
||||
"topsites_form_title_placeholder": "Tajpu titolon",
|
||||
"topsites_form_url_placeholder": "Tajpu aŭ alguu retadreson",
|
||||
"topsites_form_add_button": "Aldoni",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Recomendado por {provider}",
|
||||
"header_bookmarks_placeholder": "Aún no tienes ningún marcador.",
|
||||
"header_stories_from": "de",
|
||||
"context_menu_button_sr": "Abrir menú de contexto para {title}",
|
||||
"context_menu_button_sr": "Abrir menú contextual para {title}",
|
||||
"type_label_visited": "Visitados",
|
||||
"type_label_bookmarked": "Marcados",
|
||||
"type_label_synced": "Sincronizado desde otro dispositivo",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Editar este sitio",
|
||||
"edit_topsites_dismiss_button": "Descartar este sitio",
|
||||
"edit_topsites_add_button": "Agregar",
|
||||
"edit_topsites_add_button_tooltip": "Añadir sitio popular",
|
||||
"edit_topsites_add_button_tooltip": "Agregar sitio popular",
|
||||
"topsites_form_add_header": "Nuevo sitio popular",
|
||||
"topsites_form_edit_header": "Editar sitio popular",
|
||||
"topsites_form_title_placeholder": "Introducir un título",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "{provider} soovitab",
|
||||
"header_bookmarks_placeholder": "Sul pole veel järjehoidjaid.",
|
||||
"header_stories_from": "allikast",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Ava {title} kontekstimenüü",
|
||||
"type_label_visited": "Külastatud",
|
||||
"type_label_bookmarked": "Järjehoidjatest",
|
||||
"type_label_synced": "Sünkroniseeritud teisest seadmest",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Muuda seda saiti",
|
||||
"edit_topsites_dismiss_button": "Peida see sait",
|
||||
"edit_topsites_add_button": "Lisa",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Top saidi lisamine",
|
||||
"topsites_form_add_header": "Uue top saidi lisamine",
|
||||
"topsites_form_edit_header": "Top saidi muutmine",
|
||||
"topsites_form_title_placeholder": "Sisesta pealkiri",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "پیشنهاد شده توسط {provider}",
|
||||
"header_bookmarks_placeholder": "هنوز هیچ نشانکی ندارید.",
|
||||
"header_stories_from": "از",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "بازکردن فهرست زمینه برای {title}",
|
||||
"type_label_visited": "مشاهده شده",
|
||||
"type_label_bookmarked": "نشانک شده",
|
||||
"type_label_synced": "همگام شده از دستگاهی دیگر",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "ویرایش این سایت",
|
||||
"edit_topsites_dismiss_button": "نادیده گرفتن این سایت",
|
||||
"edit_topsites_add_button": "افزودن",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "اضافه کردن به سایت های برتر",
|
||||
"topsites_form_add_header": "سایت برتر جدید",
|
||||
"topsites_form_edit_header": "ویرایش سایت برتر",
|
||||
"topsites_form_title_placeholder": "عنوان را وارد کنید",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "{provider} द्वारा अनुशंसित",
|
||||
"header_bookmarks_placeholder": "आपके पास अभी तक कोई भी पुस्तचिन्ह नहीं है.",
|
||||
"header_stories_from": "के द्वारा",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "{title} के लिए कॉन्टेक्स्ट मेनू खोलें",
|
||||
"type_label_visited": "देखी गई",
|
||||
"type_label_bookmarked": "पुस्तचिह्न लगाया हुआ",
|
||||
"type_label_synced": "किसी अन्य उपकरण से समकालीन किया गया",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "इस साइट को संपादित करें",
|
||||
"edit_topsites_dismiss_button": "इस साइट को ख़ारिज करें",
|
||||
"edit_topsites_add_button": "जोड़ें",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "शीर्ष साइट जोड़ें",
|
||||
"topsites_form_add_header": "नई शीर्ष साइट",
|
||||
"topsites_form_edit_header": "शीर्ष साइट संपादित करें",
|
||||
"topsites_form_title_placeholder": "एक शीर्षक दर्ज करें",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Consigliati da {provider}",
|
||||
"header_bookmarks_placeholder": "Non è ancora disponibile alcun segnalibro.",
|
||||
"header_stories_from": "da",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Apri menu contestuale per {title}",
|
||||
"type_label_visited": "Visitato",
|
||||
"type_label_bookmarked": "Nei segnalibri",
|
||||
"type_label_synced": "Sincronizzato da un altro dispositivo",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Modifica questo sito",
|
||||
"edit_topsites_dismiss_button": "Ignora questo sito",
|
||||
"edit_topsites_add_button": "Aggiungi",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Aggiungi sito principale",
|
||||
"topsites_form_add_header": "Nuovi sito principale",
|
||||
"topsites_form_edit_header": "Modifica sito principale",
|
||||
"topsites_form_title_placeholder": "Inserire un titolo",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "რეკომენდებულია {provider}-ის მიერ",
|
||||
"header_bookmarks_placeholder": "სანიშნები ჯერ არაა დამატებული.",
|
||||
"header_stories_from": "მომწოდებელი:",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "კონტექსტური მენიუს გახსნა {title}",
|
||||
"type_label_visited": "მონახულებული",
|
||||
"type_label_bookmarked": "ჩანიშნული",
|
||||
"type_label_synced": "სხვა მოწყობილობიდან დასინქრონებული",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "საიტის ჩასწორება",
|
||||
"edit_topsites_dismiss_button": "საიტის დამალვა",
|
||||
"edit_topsites_add_button": "დამატება",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "რჩეული საიტის დამატება",
|
||||
"topsites_form_add_header": "ახალი საიტი რჩეულებში",
|
||||
"topsites_form_edit_header": "რჩეული საიტების ჩასწორება",
|
||||
"topsites_form_title_placeholder": "სათაურის შეყვანა",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Ұсынушы {provider}",
|
||||
"header_bookmarks_placeholder": "Сізде әлі бетбелгілер жоқ.",
|
||||
"header_stories_from": "ұсынған",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "{title} үшін контекст мәзірін ашу",
|
||||
"type_label_visited": "Қаралған",
|
||||
"type_label_bookmarked": "Бетбелгілерде",
|
||||
"type_label_synced": "Басқа құрылғыдан синхрондалған",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Бұл сайтты түзету",
|
||||
"edit_topsites_dismiss_button": "Бұл сайтты тайдыру",
|
||||
"edit_topsites_add_button": "Қосу",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Топ сайт қосу",
|
||||
"topsites_form_add_header": "Жаңа топ сайты",
|
||||
"topsites_form_edit_header": "Топ сайтын түзету",
|
||||
"topsites_form_title_placeholder": "Атауын енгізіңіз",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Rekomendavo „{provider}“",
|
||||
"header_bookmarks_placeholder": "Jūs dar neturite adresyno įrašų.",
|
||||
"header_stories_from": "iš",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Atverti kontekstinį {title} meniu",
|
||||
"type_label_visited": "Aplankyti",
|
||||
"type_label_bookmarked": "Adresyne",
|
||||
"type_label_synced": "Sinchronizuoti iš kito įrenginio",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Redaguoti šią svetainę",
|
||||
"edit_topsites_dismiss_button": "Paslėpti šią svetainę",
|
||||
"edit_topsites_add_button": "Pridėti",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Pridėti mėgstamą svetainę",
|
||||
"topsites_form_add_header": "Nauja mėgstama svetainė",
|
||||
"topsites_form_edit_header": "Redaguoti mėgstamą svetainę",
|
||||
"topsites_form_title_placeholder": "Įveskite pavadinimą",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Iesaka {provider}",
|
||||
"header_bookmarks_placeholder": "Jums vēl nav nevienas grāmatzīmes.",
|
||||
"header_stories_from": "no",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Atvērt izvēlni {title}",
|
||||
"type_label_visited": "Apmeklēta",
|
||||
"type_label_bookmarked": "Grāmatzīmēs",
|
||||
"type_label_synced": "Atsūtīta no citas ierīces",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Rediģēt šo lapu",
|
||||
"edit_topsites_dismiss_button": "Noraidīt šo lapu",
|
||||
"edit_topsites_add_button": "Pievienot",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Pievienot populāru lapu",
|
||||
"topsites_form_add_header": "Jauna populārā lapa",
|
||||
"topsites_form_edit_header": "Rediģēt populārās lapas",
|
||||
"topsites_form_title_placeholder": "Ievadiet nosaukumu",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Рекомендовано {provider}",
|
||||
"header_bookmarks_placeholder": "У вас ещё нет каких-либо закладок.",
|
||||
"header_stories_from": "от",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Открыть контекстное меню для {title}",
|
||||
"type_label_visited": "Посещено",
|
||||
"type_label_bookmarked": "В закладках",
|
||||
"type_label_synced": "Синхронизировано с другого устройства",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Изменить этот сайт",
|
||||
"edit_topsites_dismiss_button": "Скрыть этот сайт",
|
||||
"edit_topsites_add_button": "Добавить",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Добавить в топ сайтов",
|
||||
"topsites_form_add_header": "Новый сайт в топе",
|
||||
"topsites_form_edit_header": "Изменить сайт из топа",
|
||||
"topsites_form_title_placeholder": "Введите название",
|
||||
@ -92,7 +92,7 @@ window.gActivityStreamStrings = {
|
||||
"pocket_read_even_more": "Больше статей",
|
||||
"pocket_feedback_header": "Лучшее из Интернета, отобранное более чем 25 миллионами людей.",
|
||||
"pocket_description": "Откройте для себя высококачественный контент, который вы могли бы пропустить, с помощью Pocket, теперь ставшего частью Mozilla.",
|
||||
"highlights_empty_state": "Начните веб-сёрфинг, и мы покажем вам здесь некоторые из замечательных статей, видеороликов и других страниц, которые вы недавно посетили или добавили в закладки.",
|
||||
"highlights_empty_state": "Начните веб-сёрфинг, и мы покажем вам здесь некоторые из интересных статей, видеороликов и других страниц, которые вы недавно посетили или добавили в закладки.",
|
||||
"topstories_empty_state": "Вы всё прочитали. Зайдите попозже, чтобы увидеть больше лучших статей от {provider}. Не можете ждать? Выберите популярную тему, чтобы найти больше интересных статей со всего Интернета.",
|
||||
"manual_migration_explanation2": "Попробуйте Firefox с закладками, историей и паролями из другого браузера.",
|
||||
"manual_migration_cancel_button": "Нет, спасибо",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Priporoča {provider}",
|
||||
"header_bookmarks_placeholder": "Nimate še nobenih zaznamkov.",
|
||||
"header_stories_from": "od",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Odpri priročni meni za {title}",
|
||||
"type_label_visited": "Obiskano",
|
||||
"type_label_bookmarked": "Med zaznamki",
|
||||
"type_label_synced": "Sinhronizirano z druge naprave",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Uredi to stran",
|
||||
"edit_topsites_dismiss_button": "Odstrani to stran",
|
||||
"edit_topsites_add_button": "Dodaj",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Dodaj glavno stran",
|
||||
"topsites_form_add_header": "Nova glavna stran",
|
||||
"topsites_form_edit_header": "Uredi glavno stran",
|
||||
"topsites_form_title_placeholder": "Vnesite ime",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Предложио {provider}",
|
||||
"header_bookmarks_placeholder": "Још увек немате забелешке.",
|
||||
"header_stories_from": "од",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Отвори мени поља за {title}",
|
||||
"type_label_visited": "Посећено",
|
||||
"type_label_bookmarked": "Забележено",
|
||||
"type_label_synced": "Синхронизовано са другог уређаја",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "Уреди овај сајт",
|
||||
"edit_topsites_dismiss_button": "Уклони овај сајт",
|
||||
"edit_topsites_add_button": "Додај",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Додај омиљени сајт",
|
||||
"topsites_form_add_header": "Нови омиљени сајт",
|
||||
"topsites_form_edit_header": "Уреди популарне сајтове",
|
||||
"topsites_form_title_placeholder": "Унесите наслов",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "{provider}చే సిఫార్సు చేయబడినది",
|
||||
"header_bookmarks_placeholder": "మీకు ఇంకా ఎటువంటి ఇష్టాంశాలు లేవు.",
|
||||
"header_stories_from": "నుండి",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "{title} కోసం సందర్భోచిత మెనుని తెరవండి",
|
||||
"type_label_visited": "సందర్శించారు",
|
||||
"type_label_bookmarked": "ఇష్టాంశంగా గుర్తుపెట్టారు",
|
||||
"type_label_synced": "మరో పరికరం నుంచి సమకాలీకరించి తెచ్చుకున్నవి",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "ఈ సైటును మార్చు",
|
||||
"edit_topsites_dismiss_button": "ఈ సైటుని తీసివేయి",
|
||||
"edit_topsites_add_button": "జోడించు",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "అగ్రస్థాన సైటుని జోడించండి",
|
||||
"topsites_form_add_header": "కొత్త మేటి సైటు",
|
||||
"topsites_form_edit_header": "టాప్ సైట్ను సవరించండి",
|
||||
"topsites_form_title_placeholder": "శీర్షికను నమోదు చేయండి",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "Inirekomenda ni {provider}",
|
||||
"header_bookmarks_placeholder": "Wala kang anumang mga bookmark.",
|
||||
"header_stories_from": "mula sa",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"context_menu_button_sr": "Buksan ang menu ng konteksto para sa {title}",
|
||||
"type_label_visited": "Binisita",
|
||||
"type_label_bookmarked": "Bookmarked",
|
||||
"type_label_synced": "Naka-sync mula sa ibang kagamitan",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "I-edit ang site na ito",
|
||||
"edit_topsites_dismiss_button": "I-dismiss sa site na ito",
|
||||
"edit_topsites_add_button": "Idagdag",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"edit_topsites_add_button_tooltip": "Magdagdag ng Nangungunang Site",
|
||||
"topsites_form_add_header": "Bagong nangungunang site",
|
||||
"topsites_form_edit_header": "I-edit ang nangungunang site",
|
||||
"topsites_form_title_placeholder": "Magpasok ng isang pamagat",
|
||||
|
File diff suppressed because one or more lines are too long
@ -3,98 +3,98 @@ window.gActivityStreamStrings = {
|
||||
"newtab_page_title": "Yangi ichki oyna",
|
||||
"default_label_loading": "Yuklanmoqda…",
|
||||
"header_top_sites": "Ommabop saytlar",
|
||||
"header_stories": "Top Stories",
|
||||
"header_highlights": "Highlights",
|
||||
"header_visit_again": "Visit Again",
|
||||
"header_bookmarks": "Recent Bookmarks",
|
||||
"header_recommended_by": "Recommended by {provider}",
|
||||
"header_bookmarks_placeholder": "You don’t have any bookmarks yet.",
|
||||
"header_stories_from": "from",
|
||||
"context_menu_button_sr": "Open context menu for {title}",
|
||||
"type_label_visited": "Visited",
|
||||
"type_label_bookmarked": "Bookmarked",
|
||||
"type_label_synced": "Synced from another device",
|
||||
"type_label_recommended": "Trending",
|
||||
"type_label_open": "Open",
|
||||
"type_label_topic": "Topic",
|
||||
"type_label_now": "Now",
|
||||
"menu_action_bookmark": "Bookmark",
|
||||
"menu_action_remove_bookmark": "Remove Bookmark",
|
||||
"menu_action_copy_address": "Copy Address",
|
||||
"menu_action_email_link": "Email Link…",
|
||||
"menu_action_open_new_window": "Open in a New Window",
|
||||
"menu_action_open_private_window": "Open in a New Private Window",
|
||||
"menu_action_dismiss": "Dismiss",
|
||||
"menu_action_delete": "Delete from History",
|
||||
"menu_action_pin": "Pin",
|
||||
"menu_action_unpin": "Unpin",
|
||||
"confirm_history_delete_p1": "Are you sure you want to delete every instance of this page from your history?",
|
||||
"confirm_history_delete_notice_p2": "This action cannot be undone.",
|
||||
"menu_action_save_to_pocket": "Save to Pocket",
|
||||
"search_for_something_with": "Search for {search_term} with:",
|
||||
"search_button": "Search",
|
||||
"search_header": "{search_engine_name} Search",
|
||||
"search_web_placeholder": "Search the Web",
|
||||
"search_settings": "Change Search Settings",
|
||||
"section_info_option": "Info",
|
||||
"section_info_send_feedback": "Send Feedback",
|
||||
"section_info_privacy_notice": "Privacy Notice",
|
||||
"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": "Learn how it works.",
|
||||
"section_disclaimer_topstories_buttontext": "Okay, got it",
|
||||
"welcome_title": "Welcome to new tab",
|
||||
"welcome_body": "Firefox will use this space to show your most relevant bookmarks, articles, videos, and pages you’ve recently visited, so you can get back to them easily.",
|
||||
"welcome_label": "Identifying your Highlights",
|
||||
"header_stories": "Ommabop maqolalar",
|
||||
"header_highlights": "Ajratilgan saytlar",
|
||||
"header_visit_again": "Yana tashrif buyuring",
|
||||
"header_bookmarks": "So‘nggi xatcho‘plar",
|
||||
"header_recommended_by": "{provider} tomonidan tavsiya qilingan",
|
||||
"header_bookmarks_placeholder": "Sizda hali hech qanday xatcho‘p yo‘q.",
|
||||
"header_stories_from": "Sayti:",
|
||||
"context_menu_button_sr": "{title} uchun menyu matnini ochish",
|
||||
"type_label_visited": "Kirilgan",
|
||||
"type_label_bookmarked": "Xatcho‘pga qo‘shilgan",
|
||||
"type_label_synced": "Boshqa qurilmadan sinxronlangan",
|
||||
"type_label_recommended": "Trendda",
|
||||
"type_label_open": "Ochiq",
|
||||
"type_label_topic": "Mavzu",
|
||||
"type_label_now": "Hozir",
|
||||
"menu_action_bookmark": "Xatcho‘p",
|
||||
"menu_action_remove_bookmark": "Xatcho‘pni olib tashlash",
|
||||
"menu_action_copy_address": "Manzildan nusxa olish",
|
||||
"menu_action_email_link": "E-pochta havolasi…",
|
||||
"menu_action_open_new_window": "Yangi oynada ochish",
|
||||
"menu_action_open_private_window": "Yangi maxfiy oynada ochish",
|
||||
"menu_action_dismiss": "Rad etish",
|
||||
"menu_action_delete": "Tarixdan o‘chirish",
|
||||
"menu_action_pin": "Yopishtirish",
|
||||
"menu_action_unpin": "Ajratish",
|
||||
"confirm_history_delete_p1": "Ushbu sahifaning har bir nusxasini tarixingizdan o‘chirmoqchimisiz?",
|
||||
"confirm_history_delete_notice_p2": "Bu amalni ortga qaytarib bo‘lmaydi.",
|
||||
"menu_action_save_to_pocket": "Pocket xizmatiga saqlash",
|
||||
"search_for_something_with": "{search_term}ni",
|
||||
"search_button": "Qidiruv",
|
||||
"search_header": "{search_engine_name} Qidiruv bilan izlash",
|
||||
"search_web_placeholder": "Internetda izlash",
|
||||
"search_settings": "Qidiruv sozlamalarini o‘zgartrirish",
|
||||
"section_info_option": "Ma’lumot",
|
||||
"section_info_send_feedback": "Fikr-mulohaza yuborish",
|
||||
"section_info_privacy_notice": "Maxfiylik qaydlari",
|
||||
"section_disclaimer_topstories": "Internetdagi eng qiziqarli maqolalar siz o‘qiyotgan ma’lumotlar asosida. Hozirda Mozillaning qismiga aylangan Pocket xizmatidan.",
|
||||
"section_disclaimer_topstories_linktext": "Uning qanday ishlashini o‘rganing.",
|
||||
"section_disclaimer_topstories_buttontext": "Ok, tushundim",
|
||||
"welcome_title": "Yangi ichki oynaga xush kelibsiz",
|
||||
"welcome_body": "Firefox bu maydondan so‘nggi tegishli xatcho‘plar, maqolalar, videolar va siz kirgan oxirgi saytlarni ko‘rsatish uchun foydalanadi. Demak, ularga kirish yanada osonlashadi.",
|
||||
"welcome_label": "Ajratib ko‘rsatilgan saytlar aniqlanmoqda",
|
||||
"time_label_less_than_minute": "<1m",
|
||||
"time_label_minute": "{number}m",
|
||||
"time_label_hour": "{number}h",
|
||||
"time_label_day": "{number}d",
|
||||
"settings_pane_button_label": "Customize your New Tab page",
|
||||
"settings_pane_header": "New Tab Preferences",
|
||||
"settings_pane_body2": "Choose what you see on this page.",
|
||||
"settings_pane_search_header": "Search",
|
||||
"settings_pane_search_body": "Search the Web from your new tab.",
|
||||
"settings_pane_topsites_header": "Top Sites",
|
||||
"settings_pane_topsites_body": "Access the websites you visit most.",
|
||||
"settings_pane_topsites_options_showmore": "Show two rows",
|
||||
"settings_pane_bookmarks_header": "Recent Bookmarks",
|
||||
"settings_pane_bookmarks_body": "Your newly created bookmarks in one handy location.",
|
||||
"settings_pane_visit_again_header": "Visit Again",
|
||||
"settings_pane_visit_again_body": "Firefox will show you parts of your browsing history that you might want to remember or get back to.",
|
||||
"settings_pane_highlights_header": "Highlights",
|
||||
"settings_pane_highlights_body2": "Find your way back to interesting things you’ve recently visited or bookmarked.",
|
||||
"settings_pane_highlights_options_bookmarks": "Bookmarks",
|
||||
"settings_pane_highlights_options_visited": "Visited Sites",
|
||||
"settings_pane_snippets_header": "Snippets",
|
||||
"time_label_hour": "{number}s",
|
||||
"time_label_day": "{number}k",
|
||||
"settings_pane_button_label": "Yangi ichki oyna sahifasini sozlash",
|
||||
"settings_pane_header": "Yangi ichki oyna parametrlari",
|
||||
"settings_pane_body2": "Bu sahifada nimani ko‘rishni xohlasangiz, o‘shani tanlang.",
|
||||
"settings_pane_search_header": "Izlash",
|
||||
"settings_pane_search_body": "Yangi ichki oynada internetdan izlash.",
|
||||
"settings_pane_topsites_header": "Ommabop saytlar",
|
||||
"settings_pane_topsites_body": "Eng ko‘p kirilgan saytlarga kirish.",
|
||||
"settings_pane_topsites_options_showmore": "Ikki qatorda ko‘rsatish",
|
||||
"settings_pane_bookmarks_header": "So‘nggi xatcho‘plar",
|
||||
"settings_pane_bookmarks_body": "Yangi yaratilgan xatcho‘plar yagona qo‘l uzatsa yetadigan joyda.",
|
||||
"settings_pane_visit_again_header": "Yana tashrif buyuring",
|
||||
"settings_pane_visit_again_body": "Firefox siz esalb qolmoqchi yoki yana kirmoqchi bo‘lgan brauzer tarixi qismini ko‘rsatadi.",
|
||||
"settings_pane_highlights_header": "Ajratilgan saytlar",
|
||||
"settings_pane_highlights_body2": "So‘nggi kirilgan qiziqarli saytlar yoki xatcho‘plarga qaytish yo‘lini toping.",
|
||||
"settings_pane_highlights_options_bookmarks": "Xatcho‘plar",
|
||||
"settings_pane_highlights_options_visited": "Kirilgan saytlar",
|
||||
"settings_pane_snippets_header": "Parchalar",
|
||||
"settings_pane_snippets_body": "Read short and sweet updates from Mozilla about Firefox, internet culture, and the occasional random meme.",
|
||||
"settings_pane_done_button": "Done",
|
||||
"settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
|
||||
"edit_topsites_button_text": "Edit",
|
||||
"edit_topsites_button_label": "Customize your Top Sites section",
|
||||
"edit_topsites_showmore_button": "Show More",
|
||||
"edit_topsites_showless_button": "Show Fewer",
|
||||
"edit_topsites_done_button": "Done",
|
||||
"edit_topsites_pin_button": "Pin this site",
|
||||
"edit_topsites_unpin_button": "Unpin this site",
|
||||
"edit_topsites_edit_button": "Edit this site",
|
||||
"edit_topsites_dismiss_button": "Dismiss this site",
|
||||
"edit_topsites_add_button": "Add",
|
||||
"edit_topsites_add_button_tooltip": "Add Top Site",
|
||||
"topsites_form_add_header": "New Top Site",
|
||||
"topsites_form_edit_header": "Edit Top Site",
|
||||
"topsites_form_title_placeholder": "Enter a title",
|
||||
"topsites_form_url_placeholder": "Type or paste a URL",
|
||||
"topsites_form_add_button": "Add",
|
||||
"topsites_form_save_button": "Save",
|
||||
"topsites_form_cancel_button": "Cancel",
|
||||
"topsites_form_url_validation": "Valid URL required",
|
||||
"pocket_read_more": "Popular Topics:",
|
||||
"pocket_read_even_more": "View More Stories",
|
||||
"pocket_feedback_header": "The best of the web, curated by over 25 million people.",
|
||||
"settings_pane_done_button": "Tayyor",
|
||||
"settings_pane_topstories_options_sponsored": "Homiylik maqolalarini ko‘rsatish",
|
||||
"edit_topsites_button_text": "Tahrirlash",
|
||||
"edit_topsites_button_label": "Ommabop saytlar bo‘limini sozlash",
|
||||
"edit_topsites_showmore_button": "Ko‘proq",
|
||||
"edit_topsites_showless_button": "Kamroq",
|
||||
"edit_topsites_done_button": "Tayyor",
|
||||
"edit_topsites_pin_button": "Saytni qistirish",
|
||||
"edit_topsites_unpin_button": "Saytni ajratish",
|
||||
"edit_topsites_edit_button": "Bu saytni tahrirlash",
|
||||
"edit_topsites_dismiss_button": "Bu saytni bekor qilish",
|
||||
"edit_topsites_add_button": "Qo‘shish",
|
||||
"edit_topsites_add_button_tooltip": "Ommabop saytga qo‘shish",
|
||||
"topsites_form_add_header": "Yangi ommabop sayt",
|
||||
"topsites_form_edit_header": "Ommabop saytni tahrirlash",
|
||||
"topsites_form_title_placeholder": "Nomini kiriting",
|
||||
"topsites_form_url_placeholder": "URL manzilini kiriting",
|
||||
"topsites_form_add_button": "Qo‘shish",
|
||||
"topsites_form_save_button": "Saqlash",
|
||||
"topsites_form_cancel_button": "Bekor qilish",
|
||||
"topsites_form_url_validation": "URL manzilini bexato kiriting",
|
||||
"pocket_read_more": "Mashhur mavzular:",
|
||||
"pocket_read_even_more": "Yana maqolalar ko‘rish",
|
||||
"pocket_feedback_header": "25 million odam tomonidan boshqariladigan eng zo‘r veb.",
|
||||
"pocket_description": "Discover high-quality content you might otherwise miss, with help from Pocket, now part of Mozilla.",
|
||||
"highlights_empty_state": "Start browsing, and we’ll show some of the great articles, videos, and other pages you’ve recently visited or bookmarked here.",
|
||||
"topstories_empty_state": "You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.",
|
||||
"manual_migration_explanation2": "Try Firefox with the bookmarks, history and passwords from another browser.",
|
||||
"manual_migration_cancel_button": "Yoʻq, kerak emas",
|
||||
"manual_migration_import_button": "Import Now"
|
||||
"manual_migration_import_button": "Hozir import qilish"
|
||||
};
|
||||
|
@ -53,17 +53,17 @@ window.gActivityStreamStrings = {
|
||||
"settings_pane_header": "Tùy chỉnh cho tab mới",
|
||||
"settings_pane_body2": "Chọn những gì bạn thấy trên trang này.",
|
||||
"settings_pane_search_header": "Tìm kiếm",
|
||||
"settings_pane_search_body": "Search the Web from your new tab.",
|
||||
"settings_pane_search_body": "Tìm kiếm Web từ thẻ mới của bạn.",
|
||||
"settings_pane_topsites_header": "Các trang Web hàng đầu",
|
||||
"settings_pane_topsites_body": "Truy cập vào các trang web mà bạn truy cập vào nhiều nhất.",
|
||||
"settings_pane_topsites_options_showmore": "Hiển thị hai hàng",
|
||||
"settings_pane_bookmarks_header": "Recent Bookmarks",
|
||||
"settings_pane_bookmarks_header": "Trang đánh dấu gần đây",
|
||||
"settings_pane_bookmarks_body": "Your newly created bookmarks in one handy location.",
|
||||
"settings_pane_visit_again_header": "Visit Again",
|
||||
"settings_pane_visit_again_header": "Truy cập lại",
|
||||
"settings_pane_visit_again_body": "Firefox will show you parts of your browsing history that you might want to remember or get back to.",
|
||||
"settings_pane_highlights_header": "Highlights",
|
||||
"settings_pane_highlights_header": "Nổi bật",
|
||||
"settings_pane_highlights_body2": "Find your way back to interesting things you’ve recently visited or bookmarked.",
|
||||
"settings_pane_highlights_options_bookmarks": "Bookmarks",
|
||||
"settings_pane_highlights_options_bookmarks": "Trang đánh dấu",
|
||||
"settings_pane_highlights_options_visited": "Visited Sites",
|
||||
"settings_pane_snippets_header": "Snippets",
|
||||
"settings_pane_snippets_body": "Read short and sweet updates from Mozilla about Firefox, internet culture, and the occasional random meme.",
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ window.gActivityStreamStrings = {
|
||||
"header_recommended_by": "{provider} 推薦",
|
||||
"header_bookmarks_placeholder": "您還沒有任何書籤。",
|
||||
"header_stories_from": "來自",
|
||||
"context_menu_button_sr": "打开 {title} 的上下文菜单",
|
||||
"context_menu_button_sr": "開啟 {title} 的右鍵選單",
|
||||
"type_label_visited": "造訪過的網站",
|
||||
"type_label_bookmarked": "已加入書籤",
|
||||
"type_label_synced": "從其他裝置同步過來",
|
||||
@ -79,7 +79,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "編輯此網站",
|
||||
"edit_topsites_dismiss_button": "忽略此網站",
|
||||
"edit_topsites_add_button": "新增",
|
||||
"edit_topsites_add_button_tooltip": "添加常用网站",
|
||||
"edit_topsites_add_button_tooltip": "新增熱門網站",
|
||||
"topsites_form_add_header": "新增熱門網站",
|
||||
"topsites_form_edit_header": "編輯熱門網站",
|
||||
"topsites_form_title_placeholder": "輸入標題",
|
||||
|
@ -3,10 +3,7 @@ window.gActivityStreamPrerenderedState = {
|
||||
"TopSites": {
|
||||
"initialized": false,
|
||||
"rows": [],
|
||||
"editForm": {
|
||||
"visible": false,
|
||||
"index": -1
|
||||
}
|
||||
"editForm": null
|
||||
},
|
||||
"App": {
|
||||
"initialized": false,
|
||||
@ -21,7 +18,7 @@ window.gActivityStreamPrerenderedState = {
|
||||
"migrationExpired": true,
|
||||
"showTopSites": true,
|
||||
"showSearch": true,
|
||||
"topSitesCount": 12,
|
||||
"topSitesRows": 2,
|
||||
"collapseTopSites": false,
|
||||
"section.highlights.collapsed": false,
|
||||
"section.topstories.collapsed": false,
|
||||
|
@ -41,10 +41,10 @@ describe("ActionCreators", () => {
|
||||
assert.isUndefined(action.meta.fromTarget);
|
||||
});
|
||||
});
|
||||
describe("SendToMain", () => {
|
||||
describe("AlsoToMain", () => {
|
||||
it("should create the right action", () => {
|
||||
const action = {type: "FOO", data: "BAR"};
|
||||
const newAction = ac.SendToMain(action);
|
||||
const newAction = ac.AlsoToMain(action);
|
||||
assert.deepEqual(newAction, {
|
||||
type: "FOO",
|
||||
data: "BAR",
|
||||
@ -53,24 +53,24 @@ describe("ActionCreators", () => {
|
||||
});
|
||||
it("should add the fromTarget if it was supplied", () => {
|
||||
const action = {type: "FOO", data: "BAR"};
|
||||
const newAction = ac.SendToMain(action, "port123");
|
||||
const newAction = ac.AlsoToMain(action, "port123");
|
||||
assert.equal(newAction.meta.fromTarget, "port123");
|
||||
});
|
||||
describe("isSendToMain", () => {
|
||||
it("should return true if action is SendToMain", () => {
|
||||
const newAction = ac.SendToMain({type: "FOO"});
|
||||
it("should return true if action is AlsoToMain", () => {
|
||||
const newAction = ac.AlsoToMain({type: "FOO"});
|
||||
assert.isTrue(au.isSendToMain(newAction));
|
||||
});
|
||||
it("should return false if action is not SendToMain", () => {
|
||||
it("should return false if action is not AlsoToMain", () => {
|
||||
assert.isFalse(au.isSendToMain({type: "FOO"}));
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("SendToContent", () => {
|
||||
describe("AlsoToOneContent", () => {
|
||||
it("should create the right action", () => {
|
||||
const action = {type: "FOO", data: "BAR"};
|
||||
const targetId = "abc123";
|
||||
const newAction = ac.SendToContent(action, targetId);
|
||||
const newAction = ac.AlsoToOneContent(action, targetId);
|
||||
assert.deepEqual(newAction, {
|
||||
type: "FOO",
|
||||
data: "BAR",
|
||||
@ -79,30 +79,30 @@ describe("ActionCreators", () => {
|
||||
});
|
||||
it("should throw if no targetId is provided", () => {
|
||||
assert.throws(() => {
|
||||
ac.SendToContent({type: "FOO"});
|
||||
ac.AlsoToOneContent({type: "FOO"});
|
||||
});
|
||||
});
|
||||
describe("isSendToContent", () => {
|
||||
it("should return true if action is SendToContent", () => {
|
||||
const newAction = ac.SendToContent({type: "FOO"}, "foo123");
|
||||
assert.isTrue(au.isSendToContent(newAction));
|
||||
describe("isSendToOneContent", () => {
|
||||
it("should return true if action is AlsoToOneContent", () => {
|
||||
const newAction = ac.AlsoToOneContent({type: "FOO"}, "foo123");
|
||||
assert.isTrue(au.isSendToOneContent(newAction));
|
||||
});
|
||||
it("should return false if action is not SendToMain", () => {
|
||||
assert.isFalse(au.isSendToContent({type: "FOO"}));
|
||||
assert.isFalse(au.isSendToContent(ac.BroadcastToContent({type: "FOO"})));
|
||||
it("should return false if action is not AlsoToMain", () => {
|
||||
assert.isFalse(au.isSendToOneContent({type: "FOO"}));
|
||||
assert.isFalse(au.isSendToOneContent(ac.BroadcastToContent({type: "FOO"})));
|
||||
});
|
||||
});
|
||||
describe("isFromMain", () => {
|
||||
it("should return true if action is SendToContent", () => {
|
||||
const newAction = ac.SendToContent({type: "FOO"}, "foo123");
|
||||
it("should return true if action is AlsoToOneContent", () => {
|
||||
const newAction = ac.AlsoToOneContent({type: "FOO"}, "foo123");
|
||||
assert.isTrue(au.isFromMain(newAction));
|
||||
});
|
||||
it("should return true if action is BroadcastToContent", () => {
|
||||
const newAction = ac.BroadcastToContent({type: "FOO"});
|
||||
assert.isTrue(au.isFromMain(newAction));
|
||||
});
|
||||
it("should return false if action is SendToMain", () => {
|
||||
const newAction = ac.SendToMain({type: "FOO"});
|
||||
it("should return false if action is AlsoToMain", () => {
|
||||
const newAction = ac.AlsoToMain({type: "FOO"});
|
||||
assert.isFalse(au.isFromMain(newAction));
|
||||
});
|
||||
});
|
||||
@ -123,14 +123,14 @@ describe("ActionCreators", () => {
|
||||
});
|
||||
it("should return false if action is not BroadcastToContent", () => {
|
||||
assert.isFalse(au.isBroadcastToContent({type: "FOO"}));
|
||||
assert.isFalse(au.isBroadcastToContent(ac.SendToContent({type: "FOO"}, "foo123")));
|
||||
assert.isFalse(au.isBroadcastToContent(ac.AlsoToOneContent({type: "FOO"}, "foo123")));
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("SendToPreloaded", () => {
|
||||
describe("AlsoToPreloaded", () => {
|
||||
it("should create the right action", () => {
|
||||
const action = {type: "FOO", data: "BAR"};
|
||||
const newAction = ac.SendToPreloaded(action);
|
||||
const newAction = ac.AlsoToPreloaded(action);
|
||||
assert.deepEqual(newAction, {
|
||||
type: "FOO",
|
||||
data: "BAR",
|
||||
@ -139,10 +139,10 @@ describe("ActionCreators", () => {
|
||||
});
|
||||
});
|
||||
describe("isSendToPreloaded", () => {
|
||||
it("should return true if action is SendToPreloaded", () => {
|
||||
assert.isTrue(au.isSendToPreloaded(ac.SendToPreloaded({type: "FOO"})));
|
||||
it("should return true if action is AlsoToPreloaded", () => {
|
||||
assert.isTrue(au.isSendToPreloaded(ac.AlsoToPreloaded({type: "FOO"})));
|
||||
});
|
||||
it("should return false if action is not SendToPreloaded", () => {
|
||||
it("should return false if action is not AlsoToPreloaded", () => {
|
||||
assert.isFalse(au.isSendToPreloaded({type: "FOO"}));
|
||||
assert.isFalse(au.isSendToPreloaded(ac.BroadcastToContent({type: "FOO"})));
|
||||
});
|
||||
@ -152,7 +152,7 @@ describe("ActionCreators", () => {
|
||||
const data = {action: "foo"};
|
||||
assert.equal(ac.UserEvent(data).data, data);
|
||||
});
|
||||
it("should wrap with SendToMain", () => {
|
||||
it("should wrap with AlsoToMain", () => {
|
||||
const action = ac.UserEvent({action: "foo"});
|
||||
assert.isTrue(au.isSendToMain(action), "isSendToMain");
|
||||
});
|
||||
@ -162,10 +162,10 @@ describe("ActionCreators", () => {
|
||||
const data = {action: "foo"};
|
||||
assert.equal(ac.UndesiredEvent(data).data, data);
|
||||
});
|
||||
it("should wrap with SendToMain if in UI code", () => {
|
||||
it("should wrap with AlsoToMain if in UI code", () => {
|
||||
assert.isTrue(au.isSendToMain(ac.UndesiredEvent({action: "foo"})), "isSendToMain");
|
||||
});
|
||||
it("should not wrap with SendToMain if not in UI code", () => {
|
||||
it("should not wrap with AlsoToMain if not in UI code", () => {
|
||||
const action = ac.UndesiredEvent({action: "foo"}, BACKGROUND_PROCESS);
|
||||
assert.isFalse(au.isSendToMain(action), "isSendToMain");
|
||||
});
|
||||
@ -175,10 +175,10 @@ describe("ActionCreators", () => {
|
||||
const data = {action: "foo"};
|
||||
assert.equal(ac.UndesiredEvent(data).data, data);
|
||||
});
|
||||
it("should wrap with SendToMain if in UI code", () => {
|
||||
it("should wrap with AlsoToMain if in UI code", () => {
|
||||
assert.isTrue(au.isSendToMain(ac.PerfEvent({action: "foo"})), "isSendToMain");
|
||||
});
|
||||
it("should not wrap with SendToMain if not in UI code", () => {
|
||||
it("should not wrap with AlsoToMain if not in UI code", () => {
|
||||
const action = ac.PerfEvent({action: "foo"}, BACKGROUND_PROCESS);
|
||||
assert.isFalse(au.isSendToMain(action), "isSendToMain");
|
||||
});
|
||||
@ -188,21 +188,37 @@ describe("ActionCreators", () => {
|
||||
const data = {action: "foo"};
|
||||
assert.equal(ac.ImpressionStats(data).data, data);
|
||||
});
|
||||
it("should wrap with SendToMain if in UI code", () => {
|
||||
it("should wrap with AlsoToMain if in UI code", () => {
|
||||
assert.isTrue(au.isSendToMain(ac.ImpressionStats({action: "foo"})), "isSendToMain");
|
||||
});
|
||||
it("should not wrap with SendToMain if not in UI code", () => {
|
||||
it("should not wrap with AlsoToMain if not in UI code", () => {
|
||||
const action = ac.ImpressionStats({action: "foo"}, BACKGROUND_PROCESS);
|
||||
assert.isFalse(au.isSendToMain(action), "isSendToMain");
|
||||
});
|
||||
});
|
||||
describe("WebExtEvent", () => {
|
||||
it("should set the provided type", () => {
|
||||
const action = ac.WebExtEvent(at.WEBEXT_CLICK, {source: "MyExtension", url: "foo.com"});
|
||||
assert.equal(action.type, at.WEBEXT_CLICK);
|
||||
});
|
||||
it("should set the provided data", () => {
|
||||
const data = {source: "MyExtension", url: "foo.com"};
|
||||
const action = ac.WebExtEvent(at.WEBEXT_CLICK, data);
|
||||
assert.equal(action.data, data);
|
||||
});
|
||||
it("should throw if the 'source' property is missing", () => {
|
||||
assert.throws(() => {
|
||||
ac.WebExtEvent(at.WEBEXT_CLICK, {});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("ActionUtils", () => {
|
||||
describe("getPortIdOfSender", () => {
|
||||
it("should return the PortID from a SendToMain action", () => {
|
||||
it("should return the PortID from a AlsoToMain action", () => {
|
||||
const portID = "foo123";
|
||||
const result = au.getPortIdOfSender(ac.SendToMain({type: "FOO"}, portID));
|
||||
const result = au.getPortIdOfSender(ac.AlsoToMain({type: "FOO"}, portID));
|
||||
assert.equal(result, portID);
|
||||
});
|
||||
});
|
||||
|
@ -35,18 +35,14 @@ describe("Reducers", () => {
|
||||
const nextState = TopSites(undefined, {type: at.TOP_SITES_UPDATED});
|
||||
assert.equal(nextState, INITIAL_STATE.TopSites);
|
||||
});
|
||||
it("should set editForm.visible to true on TOP_SITES_EDIT", () => {
|
||||
const nextState = TopSites(undefined, {type: at.TOP_SITES_EDIT, data: {index: 3}});
|
||||
assert.isTrue(nextState.editForm.visible);
|
||||
});
|
||||
it("should set editForm.site to action.data on TOP_SITES_EDIT", () => {
|
||||
const data = {index: 7};
|
||||
const nextState = TopSites(undefined, {type: at.TOP_SITES_EDIT, data});
|
||||
assert.equal(nextState.editForm.index, data.index);
|
||||
});
|
||||
it("should set editForm.visible to false on TOP_SITES_CANCEL_EDIT", () => {
|
||||
it("should set editForm to null on TOP_SITES_CANCEL_EDIT", () => {
|
||||
const nextState = TopSites(undefined, {type: at.TOP_SITES_CANCEL_EDIT});
|
||||
assert.isFalse(nextState.editForm.visible);
|
||||
assert.isNull(nextState.editForm);
|
||||
});
|
||||
it("should add screenshots for SCREENSHOT_UPDATED", () => {
|
||||
const oldState = {rows: [{url: "foo.com"}, {url: "bar.com"}]};
|
||||
|
@ -260,14 +260,14 @@ describe("ActivityStreamMessageChannel", () => {
|
||||
const t = {portID: "foo", sendAsyncMessage: sinon.spy()};
|
||||
mm.createChannel();
|
||||
mm.channel.messagePorts = [t];
|
||||
const action = ac.SendToContent({type: "HELLO"}, "foo");
|
||||
const action = ac.AlsoToOneContent({type: "HELLO"}, "foo");
|
||||
mm.send(action, "foo");
|
||||
assert.calledWith(t.sendAsyncMessage, DEFAULT_OPTIONS.outgoingMessageName, action);
|
||||
});
|
||||
it("should not throw if the target isn't around", () => {
|
||||
mm.createChannel();
|
||||
// port is not added to the channel
|
||||
const action = ac.SendToContent({type: "HELLO"}, "foo");
|
||||
const action = ac.AlsoToOneContent({type: "HELLO"}, "foo");
|
||||
|
||||
assert.doesNotThrow(() => mm.send(action, "foo"));
|
||||
});
|
||||
@ -292,7 +292,7 @@ describe("ActivityStreamMessageChannel", () => {
|
||||
};
|
||||
mm.createChannel();
|
||||
mm.channel.messagePorts.push(port);
|
||||
const action = ac.SendToPreloaded({type: "HELLO", data: 10});
|
||||
const action = ac.AlsoToPreloaded({type: "HELLO", data: 10});
|
||||
mm.sendToPreloaded(action);
|
||||
assert.calledWith(port.sendAsyncMessage, DEFAULT_OPTIONS.outgoingMessageName, action);
|
||||
});
|
||||
@ -308,7 +308,7 @@ describe("ActivityStreamMessageChannel", () => {
|
||||
mm.createChannel();
|
||||
mm.channel.messagePorts.push(port);
|
||||
mm.channel.messagePorts.push(port);
|
||||
mm.sendToPreloaded(ac.SendToPreloaded({type: "HELLO", data: 10}));
|
||||
mm.sendToPreloaded(ac.AlsoToPreloaded({type: "HELLO", data: 10}));
|
||||
assert.calledTwice(port.sendAsyncMessage);
|
||||
});
|
||||
it("should not send the message to the preloaded browser if there's no data and a preloaded browser does not exists", () => {
|
||||
@ -322,7 +322,7 @@ describe("ActivityStreamMessageChannel", () => {
|
||||
};
|
||||
mm.createChannel();
|
||||
mm.channel.messagePorts.push(port);
|
||||
const action = ac.SendToPreloaded({type: "HELLO"});
|
||||
const action = ac.AlsoToPreloaded({type: "HELLO"});
|
||||
mm.sendToPreloaded(action);
|
||||
assert.notCalled(port.sendAsyncMessage);
|
||||
});
|
||||
@ -331,7 +331,7 @@ describe("ActivityStreamMessageChannel", () => {
|
||||
describe("Handling actions", () => {
|
||||
describe("#onActionFromContent", () => {
|
||||
beforeEach(() => mm.onActionFromContent({type: "FOO"}, "foo"));
|
||||
it("should dispatch a SendToMain action", () => {
|
||||
it("should dispatch a AlsoToMain action", () => {
|
||||
assert.calledOnce(dispatch);
|
||||
const [action] = dispatch.firstCall.args;
|
||||
assert.equal(action.type, "FOO", "action.type");
|
||||
@ -350,25 +350,25 @@ describe("ActivityStreamMessageChannel", () => {
|
||||
store.dispatch({type: "ADD", data: 10});
|
||||
assert.equal(store.getState(), 10);
|
||||
});
|
||||
it("should not call next if skipMain is true", () => {
|
||||
store.dispatch({type: "ADD", data: 10, meta: {skipMain: true}});
|
||||
assert.equal(store.getState(), 0);
|
||||
|
||||
it("should call .send but not affect the main store if an OnlyToOneContent action is dispatched", () => {
|
||||
sinon.stub(mm, "send");
|
||||
const action = ac.SendToContent({type: "ADD", data: 10, meta: {skipMain: true}}, "foo");
|
||||
const action = ac.OnlyToOneContent({type: "ADD", data: 10}, "foo");
|
||||
mm.createChannel();
|
||||
|
||||
store.dispatch(action);
|
||||
|
||||
assert.calledWith(mm.send, action);
|
||||
assert.equal(store.getState(), 0);
|
||||
});
|
||||
it("should call .send if the action is SendToContent", () => {
|
||||
it("should call .send and update the main store if an AlsoToOneContent action is dispatched", () => {
|
||||
sinon.stub(mm, "send");
|
||||
const action = ac.SendToContent({type: "FOO"}, "foo");
|
||||
|
||||
const action = ac.AlsoToOneContent({type: "ADD", data: 10}, "foo");
|
||||
mm.createChannel();
|
||||
|
||||
store.dispatch(action);
|
||||
|
||||
assert.calledWith(mm.send, action);
|
||||
assert.equal(store.getState(), 10);
|
||||
});
|
||||
it("should call .broadcast if the action is BroadcastToContent", () => {
|
||||
sinon.stub(mm, "broadcast");
|
||||
@ -379,9 +379,9 @@ describe("ActivityStreamMessageChannel", () => {
|
||||
|
||||
assert.calledWith(mm.broadcast, action);
|
||||
});
|
||||
it("should call .sendToPreloaded if the action is SendToPreloaded", () => {
|
||||
it("should call .sendToPreloaded if the action is AlsoToPreloaded", () => {
|
||||
sinon.stub(mm, "sendToPreloaded");
|
||||
const action = ac.SendToPreloaded({type: "FOO"});
|
||||
const action = ac.AlsoToPreloaded({type: "FOO"});
|
||||
|
||||
mm.createChannel();
|
||||
store.dispatch(action);
|
||||
|
@ -5,7 +5,7 @@ describe("NewTabInit", () => {
|
||||
let instance;
|
||||
let store;
|
||||
let STATE;
|
||||
const requestFromTab = portID => instance.onAction(ac.SendToMain(
|
||||
const requestFromTab = portID => instance.onAction(ac.AlsoToMain(
|
||||
{type: at.NEW_TAB_STATE_REQUEST}, portID));
|
||||
beforeEach(() => {
|
||||
STATE = {};
|
||||
@ -16,7 +16,7 @@ describe("NewTabInit", () => {
|
||||
it("should reply with a copy of the state immediately", () => {
|
||||
requestFromTab(123);
|
||||
|
||||
const resp = ac.SendToContent({type: at.NEW_TAB_INITIAL_STATE, data: STATE}, 123);
|
||||
const resp = ac.AlsoToOneContent({type: at.NEW_TAB_INITIAL_STATE, data: STATE}, 123);
|
||||
assert.calledWith(store.dispatch, resp);
|
||||
});
|
||||
describe("early / simulated new tabs", () => {
|
||||
@ -30,7 +30,7 @@ describe("NewTabInit", () => {
|
||||
it("should dispatch if not replied yet", () => {
|
||||
requestFromTab("foo");
|
||||
|
||||
assert.calledWith(store.dispatch, ac.SendToContent({type: at.NEW_TAB_INITIAL_STATE, data: STATE}, "foo"));
|
||||
assert.calledWith(store.dispatch, ac.AlsoToOneContent({type: at.NEW_TAB_INITIAL_STATE, data: STATE}, "foo"));
|
||||
});
|
||||
it("should dispatch once for multiple requests", () => {
|
||||
requestFromTab("foo");
|
||||
@ -54,11 +54,11 @@ describe("NewTabInit", () => {
|
||||
});
|
||||
it("should clean up when tabs close", () => {
|
||||
assert.propertyVal(instance._repliedEarlyTabs, "size", 2);
|
||||
instance.onAction(ac.SendToMain({type: at.NEW_TAB_UNLOAD}, "foo"));
|
||||
instance.onAction(ac.AlsoToMain({type: at.NEW_TAB_UNLOAD}, "foo"));
|
||||
assert.propertyVal(instance._repliedEarlyTabs, "size", 1);
|
||||
instance.onAction(ac.SendToMain({type: at.NEW_TAB_UNLOAD}, "foo"));
|
||||
instance.onAction(ac.AlsoToMain({type: at.NEW_TAB_UNLOAD}, "foo"));
|
||||
assert.propertyVal(instance._repliedEarlyTabs, "size", 1);
|
||||
instance.onAction(ac.SendToMain({type: at.NEW_TAB_UNLOAD}, "bar"));
|
||||
instance.onAction(ac.AlsoToMain({type: at.NEW_TAB_UNLOAD}, "bar"));
|
||||
assert.propertyVal(instance._repliedEarlyTabs, "size", 0);
|
||||
});
|
||||
});
|
||||
|
@ -166,6 +166,7 @@ describe("PlacesFeed", () => {
|
||||
assert.equal(url, "foo.com");
|
||||
assert.equal(where, "current");
|
||||
assert.propertyVal(params, "private", false);
|
||||
assert.propertyVal(params, "triggeringPrincipal", undefined);
|
||||
});
|
||||
it("should open link with referrer on OPEN_LINK", () => {
|
||||
const openLinkIn = sinon.stub();
|
||||
|
@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
import {CONTENT_MESSAGE_TYPE, MAIN_MESSAGE_TYPE, PRELOAD_MESSAGE_TYPE} from "common/Actions.jsm";
|
||||
import {actionCreators as ac, actionTypes as at, CONTENT_MESSAGE_TYPE, MAIN_MESSAGE_TYPE, PRELOAD_MESSAGE_TYPE} from "common/Actions.jsm";
|
||||
import {EventEmitter, GlobalOverrider} from "test/unit/utils";
|
||||
import {SectionsFeed, SectionsManager} from "lib/SectionsManager.jsm";
|
||||
|
||||
@ -209,6 +209,27 @@ describe("SectionsManager", () => {
|
||||
assert.notCalled(spy);
|
||||
});
|
||||
});
|
||||
describe("#removeSectionCard", () => {
|
||||
it("should dispatch an SECTION_UPDATE action in which cards corresponding to the given url are removed", () => {
|
||||
const rows = [{url: "foo.com"}, {url: "bar.com"}];
|
||||
|
||||
SectionsManager.addSection(FAKE_ID, Object.assign({}, FAKE_OPTIONS, {rows}));
|
||||
const spy = sinon.spy();
|
||||
SectionsManager.on(SectionsManager.UPDATE_SECTION, spy);
|
||||
SectionsManager.removeSectionCard(FAKE_ID, "foo.com");
|
||||
|
||||
assert.calledOnce(spy);
|
||||
assert.equal(spy.firstCall.args[1], FAKE_ID);
|
||||
assert.deepEqual(spy.firstCall.args[2].rows, [{url: "bar.com"}]);
|
||||
});
|
||||
it("should do nothing if the section doesn't exist", () => {
|
||||
SectionsManager.removeSection(FAKE_ID);
|
||||
const spy = sinon.spy();
|
||||
SectionsManager.on(SectionsManager.UPDATE_SECTION, spy);
|
||||
SectionsManager.removeSectionCard(FAKE_ID, "bar.com");
|
||||
assert.notCalled(spy);
|
||||
});
|
||||
});
|
||||
describe("#updateBookmarkMetadata", () => {
|
||||
beforeEach(() => {
|
||||
let rows = [{
|
||||
@ -464,5 +485,13 @@ describe("SectionsFeed", () => {
|
||||
|
||||
assert.calledOnce(stub);
|
||||
});
|
||||
it("should call SectionManager.removeSectionCard on WEBEXT_DISMISS", () => {
|
||||
const stub = sinon.stub(SectionsManager, "removeSectionCard");
|
||||
|
||||
feed.onAction(ac.WebExtEvent(at.WEBEXT_DISMISS, {source: "Foo", url: "bar.com"}));
|
||||
|
||||
assert.calledOnce(stub);
|
||||
assert.calledWith(stub, "Foo", "bar.com");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -290,7 +290,7 @@ describe("TelemetryFeed", () => {
|
||||
it("should create a valid event", async () => {
|
||||
const portID = "foo";
|
||||
const data = {source: "TOP_SITES", event: "CLICK"};
|
||||
const action = ac.SendToMain(ac.UserEvent(data), portID);
|
||||
const action = ac.AlsoToMain(ac.UserEvent(data), portID);
|
||||
const session = instance.addSession(portID);
|
||||
|
||||
const ping = await instance.createUserEvent(action);
|
||||
@ -315,7 +315,7 @@ describe("TelemetryFeed", () => {
|
||||
it("should create a valid event with a session", async () => {
|
||||
const portID = "foo";
|
||||
const data = {source: "TOP_SITES", event: "MISSING_IMAGE", value: 10};
|
||||
const action = ac.SendToMain(ac.UndesiredEvent(data), portID);
|
||||
const action = ac.AlsoToMain(ac.UndesiredEvent(data), portID);
|
||||
const session = instance.addSession(portID);
|
||||
|
||||
const ping = await instance.createUndesiredEvent(action);
|
||||
@ -575,7 +575,7 @@ describe("TelemetryFeed", () => {
|
||||
it("should call .handleNewTabInit on a NEW_TAB_INIT action", () => {
|
||||
sandbox.spy(instance, "handleNewTabInit");
|
||||
|
||||
instance.onAction(ac.SendToMain({
|
||||
instance.onAction(ac.AlsoToMain({
|
||||
type: at.NEW_TAB_INIT,
|
||||
data: {url: "about:newtab", browser}
|
||||
}));
|
||||
@ -586,7 +586,7 @@ describe("TelemetryFeed", () => {
|
||||
const stub = sandbox.stub(instance, "addSession").returns({perf: {}});
|
||||
sandbox.stub(instance, "setLoadTriggerInfo");
|
||||
|
||||
instance.onAction(ac.SendToMain({
|
||||
instance.onAction(ac.AlsoToMain({
|
||||
type: at.NEW_TAB_INIT,
|
||||
data: {url: "about:monkeys", browser}
|
||||
}, "port123"));
|
||||
@ -597,7 +597,7 @@ describe("TelemetryFeed", () => {
|
||||
it("should call .endSession() on a NEW_TAB_UNLOAD action", () => {
|
||||
const stub = sandbox.stub(instance, "endSession");
|
||||
|
||||
instance.onAction(ac.SendToMain({type: at.NEW_TAB_UNLOAD}, "port123"));
|
||||
instance.onAction(ac.AlsoToMain({type: at.NEW_TAB_UNLOAD}, "port123"));
|
||||
|
||||
assert.calledWith(stub, "port123");
|
||||
});
|
||||
@ -606,7 +606,7 @@ describe("TelemetryFeed", () => {
|
||||
const data = {some_ts: 10};
|
||||
const action = {type: at.SAVE_SESSION_PERF_DATA, data};
|
||||
|
||||
instance.onAction(ac.SendToMain(action, "port123"));
|
||||
instance.onAction(ac.AlsoToMain(action, "port123"));
|
||||
|
||||
assert.calledWith(stub, "port123", data);
|
||||
});
|
||||
@ -655,7 +655,7 @@ describe("TelemetryFeed", () => {
|
||||
sandbox.stub(instance.sessions, "get").returns(session);
|
||||
sandbox.spy(instance, "handlePagePrerendered");
|
||||
|
||||
instance.onAction(ac.SendToMain({type: at.PAGE_PRERENDERED}));
|
||||
instance.onAction(ac.AlsoToMain({type: at.PAGE_PRERENDERED}));
|
||||
|
||||
assert.calledOnce(instance.handlePagePrerendered);
|
||||
assert.ok(session.perf.is_prerendered);
|
||||
@ -669,7 +669,7 @@ describe("TelemetryFeed", () => {
|
||||
const session = {perf: {}};
|
||||
sandbox.stub(instance.sessions, "get").returns(session);
|
||||
|
||||
instance.onAction(ac.SendToMain({type: at.PAGE_PRERENDERED}));
|
||||
instance.onAction(ac.AlsoToMain({type: at.PAGE_PRERENDERED}));
|
||||
|
||||
assert.ok(session.perf.is_prerendered);
|
||||
});
|
||||
@ -680,7 +680,7 @@ describe("TelemetryFeed", () => {
|
||||
let preloadedBrowser = {getAttribute() { return "preloaded"; }};
|
||||
sandbox.stub(instance, "addSession").returns(session);
|
||||
|
||||
instance.onAction(ac.SendToMain({
|
||||
instance.onAction(ac.AlsoToMain({
|
||||
type: at.NEW_TAB_INIT,
|
||||
data: {url: "about:newtab", browser: preloadedBrowser}
|
||||
}));
|
||||
@ -692,7 +692,7 @@ describe("TelemetryFeed", () => {
|
||||
let nonPreloadedBrowser = {getAttribute() { return ""; }};
|
||||
sandbox.stub(instance, "addSession").returns(session);
|
||||
|
||||
instance.onAction(ac.SendToMain({
|
||||
instance.onAction(ac.AlsoToMain({
|
||||
type: at.NEW_TAB_INIT,
|
||||
data: {url: "about:newtab", browser: nonPreloadedBrowser}
|
||||
}));
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
|
||||
import {FakePrefs, GlobalOverrider} from "test/unit/utils";
|
||||
import {insertPinned, TOP_SITES_SHOWMORE_LENGTH} from "common/Reducers.jsm";
|
||||
import {insertPinned, TOP_SITES_DEFAULT_ROWS, TOP_SITES_MAX_SITES_PER_ROW} from "common/Reducers.jsm";
|
||||
import injector from "inject!lib/TopSitesFeed.jsm";
|
||||
import {Screenshots} from "lib/Screenshots.jsm";
|
||||
|
||||
const FAKE_FAVICON = "data987";
|
||||
const FAKE_FAVICON_SIZE = 128;
|
||||
const FAKE_FRECENCY = 200;
|
||||
const FAKE_LINKS = new Array(TOP_SITES_SHOWMORE_LENGTH).fill(null).map((v, i) => ({
|
||||
const FAKE_LINKS = new Array(TOP_SITES_DEFAULT_ROWS * TOP_SITES_MAX_SITES_PER_ROW).fill(null).map((v, i) => ({
|
||||
frecency: FAKE_FRECENCY,
|
||||
url: `http://www.site${i}.com`
|
||||
}));
|
||||
@ -76,7 +76,7 @@ describe("Top Sites Feed", () => {
|
||||
({TopSitesFeed, DEFAULT_TOP_SITES} = injector({
|
||||
"lib/ActivityStreamPrefs.jsm": {Prefs: FakePrefs},
|
||||
"common/Dedupe.jsm": {Dedupe: fakeDedupe},
|
||||
"common/Reducers.jsm": {insertPinned, TOP_SITES_SHOWMORE_LENGTH},
|
||||
"common/Reducers.jsm": {insertPinned, TOP_SITES_DEFAULT_ROWS, TOP_SITES_MAX_SITES_PER_ROW},
|
||||
"lib/FilterAdult.jsm": {filterAdult: filterAdultStub},
|
||||
"lib/Screenshots.jsm": {Screenshots: fakeScreenshot},
|
||||
"lib/TippyTopProvider.jsm": {TippyTopProvider: FakeTippyTopProvider},
|
||||
@ -87,7 +87,7 @@ describe("Top Sites Feed", () => {
|
||||
dispatch: sinon.spy(),
|
||||
getState() { return this.state; },
|
||||
state: {
|
||||
Prefs: {values: {filterAdult: false, topSitesCount: 6}},
|
||||
Prefs: {values: {filterAdult: false, topSitesRows: 2}},
|
||||
TopSites: {rows: Array(12).fill("site")}
|
||||
}
|
||||
};
|
||||
@ -219,15 +219,16 @@ describe("Top Sites Feed", () => {
|
||||
|
||||
assert.deepEqual(result, reference);
|
||||
});
|
||||
it("should only add defaults up to TOP_SITES_SHOWMORE_LENGTH", async () => {
|
||||
it("should only add defaults up to the number of visible slots", async () => {
|
||||
links = [];
|
||||
for (let i = 0; i < TOP_SITES_SHOWMORE_LENGTH - 1; i++) {
|
||||
const numVisible = TOP_SITES_DEFAULT_ROWS * TOP_SITES_MAX_SITES_PER_ROW;
|
||||
for (let i = 0; i < numVisible - 1; i++) {
|
||||
links.push({frecency: FAKE_FRECENCY, url: `foo${i}.com`});
|
||||
}
|
||||
const result = await feed.getLinksWithDefaults();
|
||||
const reference = [...links, DEFAULT_TOP_SITES[0]].map(s => Object.assign({}, s, {hostname: shortURLStub(s)}));
|
||||
|
||||
assert.lengthOf(result, TOP_SITES_SHOWMORE_LENGTH);
|
||||
assert.lengthOf(result, numVisible);
|
||||
assert.deepEqual(result, reference);
|
||||
});
|
||||
it("should not throw if NewTabUtils returns null", () => {
|
||||
@ -237,11 +238,15 @@ describe("Top Sites Feed", () => {
|
||||
});
|
||||
});
|
||||
it("should get more if the user has asked for more", async () => {
|
||||
feed.store.state.Prefs.values.topSitesCount = TOP_SITES_SHOWMORE_LENGTH + 1;
|
||||
links = new Array(4 * TOP_SITES_MAX_SITES_PER_ROW).fill(null).map((v, i) => ({
|
||||
frecency: FAKE_FRECENCY,
|
||||
url: `http://www.site${i}.com`
|
||||
}));
|
||||
feed.store.state.Prefs.values.topSitesRows = 3;
|
||||
|
||||
const result = await feed.getLinksWithDefaults();
|
||||
|
||||
assert.propertyVal(result, "length", feed.store.state.Prefs.values.topSitesCount);
|
||||
assert.propertyVal(result, "length", feed.store.state.Prefs.values.topSitesRows * TOP_SITES_MAX_SITES_PER_ROW);
|
||||
});
|
||||
});
|
||||
describe("caching", () => {
|
||||
@ -253,7 +258,7 @@ describe("Top Sites Feed", () => {
|
||||
});
|
||||
it("should ignore the cache when requesting more", async () => {
|
||||
await feed.getLinksWithDefaults();
|
||||
feed.store.state.Prefs.values.topSitesCount *= 3;
|
||||
feed.store.state.Prefs.values.topSitesRows *= 3;
|
||||
|
||||
await feed.getLinksWithDefaults();
|
||||
|
||||
@ -325,7 +330,7 @@ describe("Top Sites Feed", () => {
|
||||
beforeEach(() => {
|
||||
({TopSitesFeed, DEFAULT_TOP_SITES} = injector({
|
||||
"lib/ActivityStreamPrefs.jsm": {Prefs: FakePrefs},
|
||||
"common/Reducers.jsm": {insertPinned, TOP_SITES_SHOWMORE_LENGTH},
|
||||
"common/Reducers.jsm": {insertPinned, TOP_SITES_DEFAULT_ROWS, TOP_SITES_MAX_SITES_PER_ROW},
|
||||
"lib/Screenshots.jsm": {Screenshots: fakeScreenshot}
|
||||
}));
|
||||
sandbox.stub(global.Services.eTLD, "getPublicSuffix").returns("com");
|
||||
@ -339,7 +344,7 @@ describe("Top Sites Feed", () => {
|
||||
|
||||
const sites = await feed.getLinksWithDefaults();
|
||||
|
||||
assert.lengthOf(sites, TOP_SITES_SHOWMORE_LENGTH);
|
||||
assert.lengthOf(sites, TOP_SITES_DEFAULT_ROWS * TOP_SITES_MAX_SITES_PER_ROW);
|
||||
assert.equal(sites[0].url, fakeNewTabUtils.pinnedLinks.links[0].url);
|
||||
assert.equal(sites[1].url, fakeNewTabUtils.pinnedLinks.links[1].url);
|
||||
assert.equal(sites[0].hostname, sites[1].hostname);
|
||||
@ -425,12 +430,12 @@ describe("Top Sites Feed", () => {
|
||||
await feed.refresh({broadcast: true});
|
||||
assert.calledOnce(feed.store.dispatch);
|
||||
});
|
||||
it("should dispatch SendToPreloaded when broadcast is false", async () => {
|
||||
it("should dispatch AlsoToPreloaded when broadcast is false", async () => {
|
||||
sandbox.stub(feed, "getLinksWithDefaults").returns([]);
|
||||
await feed.refresh({broadcast: false});
|
||||
|
||||
assert.calledOnce(feed.store.dispatch);
|
||||
assert.calledWithExactly(feed.store.dispatch, ac.SendToPreloaded({
|
||||
assert.calledWithExactly(feed.store.dispatch, ac.AlsoToPreloaded({
|
||||
type: at.TOP_SITES_UPDATED,
|
||||
data: []
|
||||
}));
|
||||
@ -645,7 +650,7 @@ describe("Top Sites Feed", () => {
|
||||
assert.calledWith(fakeNewTabUtils.pinnedLinks.pin, site, 0);
|
||||
assert.calledWith(fakeNewTabUtils.pinnedLinks.pin, site1, 1);
|
||||
});
|
||||
it("should unpin the site if all slots are already pinned", () => {
|
||||
it("should unpin the last site if all slots are already pinned", () => {
|
||||
const site1 = {url: "example.com"};
|
||||
const site2 = {url: "example.org"};
|
||||
const site3 = {url: "example.net"};
|
||||
@ -653,6 +658,7 @@ describe("Top Sites Feed", () => {
|
||||
const site5 = {url: "example.info"};
|
||||
const site6 = {url: "example.news"};
|
||||
fakeNewTabUtils.pinnedLinks.links = [site1, site2, site3, site4, site5, site6];
|
||||
feed.store.state.Prefs.values.topSitesRows = 1;
|
||||
const site = {url: "foo.bar", label: "foo"};
|
||||
feed.insert({data: {site}});
|
||||
assert.equal(fakeNewTabUtils.pinnedLinks.pin.callCount, 6);
|
||||
@ -703,8 +709,41 @@ describe("Top Sites Feed", () => {
|
||||
pinnedLinks = await feed.pinnedCache.request();
|
||||
assert.propertyVal(pinnedLinks[0], "screenshot", "bar");
|
||||
});
|
||||
it("should call insert if index < 0", () => {
|
||||
const site = {url: "foo.bar", label: "foo"};
|
||||
const action = {data: {index: -1, site}};
|
||||
|
||||
sandbox.spy(feed, "insert");
|
||||
feed.pin(action);
|
||||
|
||||
assert.calledOnce(feed.insert);
|
||||
assert.calledWithExactly(feed.insert, action);
|
||||
});
|
||||
it("should not call insert if index == 0", () => {
|
||||
const site = {url: "foo.bar", label: "foo"};
|
||||
const action = {data: {index: 0, site}};
|
||||
|
||||
sandbox.spy(feed, "insert");
|
||||
feed.pin(action);
|
||||
|
||||
assert.notCalled(feed.insert);
|
||||
});
|
||||
});
|
||||
describe("#drop", () => {
|
||||
it("should correctly handle different index values", () => {
|
||||
let index = -1;
|
||||
const site = {url: "foo.bar", label: "foo"};
|
||||
const action = {data: {index, site}};
|
||||
|
||||
feed.insert(action);
|
||||
|
||||
assert.calledWith(fakeNewTabUtils.pinnedLinks.pin, site, 0);
|
||||
|
||||
index = undefined;
|
||||
feed.insert(action);
|
||||
|
||||
assert.calledWith(fakeNewTabUtils.pinnedLinks.pin, site, 0);
|
||||
});
|
||||
it("should pin site in specified slot that is free", () => {
|
||||
fakeNewTabUtils.pinnedLinks.links = [null, {url: "example.com"}];
|
||||
const site = {url: "foo.bar", label: "foo"};
|
||||
@ -734,7 +773,7 @@ describe("Top Sites Feed", () => {
|
||||
assert.calledWith(fakeNewTabUtils.pinnedLinks.pin, site1, 2);
|
||||
assert.calledWith(fakeNewTabUtils.pinnedLinks.pin, site2, 3);
|
||||
});
|
||||
it("should not insert past the topSitesCount", () => {
|
||||
it("should not insert past the visible top sites", () => {
|
||||
const site1 = {url: "foo.bar", label: "foo"};
|
||||
feed.insert({data: {index: 42, site: site1, draggedFromIndex: 0}});
|
||||
assert.notCalled(fakeNewTabUtils.pinnedLinks.pin);
|
||||
|
@ -59,10 +59,25 @@ describe("initStore", () => {
|
||||
store.dispatch({type: MERGE_STORE_ACTION, data: {number: 42}});
|
||||
assert.deepEqual(store.getState(), {number: 42});
|
||||
});
|
||||
it("should send out SendToMain actions", () => {
|
||||
const action = ac.SendToMain({type: "FOO"});
|
||||
it("should call .send and update the local store if an AlsoToMain action is dispatched", () => {
|
||||
const subscriber = sinon.spy();
|
||||
const action = ac.AlsoToMain({type: "FOO"});
|
||||
|
||||
store.subscribe(subscriber);
|
||||
store.dispatch(action);
|
||||
|
||||
assert.calledWith(global.sendAsyncMessage, OUTGOING_MESSAGE_NAME, action);
|
||||
assert.calledOnce(subscriber);
|
||||
});
|
||||
it("should call .send but not update the local store if an OnlyToMain action is dispatched", () => {
|
||||
const subscriber = sinon.spy();
|
||||
const action = ac.OnlyToMain({type: "FOO"});
|
||||
|
||||
store.subscribe(subscriber);
|
||||
store.dispatch(action);
|
||||
|
||||
assert.calledWith(global.sendAsyncMessage, OUTGOING_MESSAGE_NAME, action);
|
||||
assert.notCalled(subscriber);
|
||||
});
|
||||
it("should not send out other types of actions", () => {
|
||||
store.dispatch({type: "FOO"});
|
||||
@ -70,13 +85,13 @@ describe("initStore", () => {
|
||||
});
|
||||
describe("rehydrationMiddleware", () => {
|
||||
it("should allow NEW_TAB_STATE_REQUEST to go through", () => {
|
||||
const action = ac.SendToMain({type: at.NEW_TAB_STATE_REQUEST});
|
||||
const action = ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST});
|
||||
const next = sinon.spy();
|
||||
rehydrationMiddleware(store)(next)(action);
|
||||
assert.calledWith(next, action);
|
||||
});
|
||||
it("should dispatch an additional NEW_TAB_STATE_REQUEST if INIT was received after a request", () => {
|
||||
const requestAction = ac.SendToMain({type: at.NEW_TAB_STATE_REQUEST});
|
||||
const requestAction = ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST});
|
||||
const next = sinon.spy();
|
||||
|
||||
rehydrationMiddleware(store)(next)(requestAction);
|
||||
@ -95,7 +110,7 @@ describe("initStore", () => {
|
||||
const next = sinon.spy();
|
||||
|
||||
rehydrationMiddleware(store)(next)(ac.BroadcastToContent({type: "FOO"}));
|
||||
rehydrationMiddleware(store)(next)(ac.SendToContent({type: "FOO"}, 123));
|
||||
rehydrationMiddleware(store)(next)(ac.AlsoToOneContent({type: "FOO"}, 123));
|
||||
|
||||
assert.notCalled(next);
|
||||
});
|
||||
@ -110,7 +125,7 @@ describe("initStore", () => {
|
||||
rehydrationMiddleware(store)(next)({type: MERGE_STORE_ACTION});
|
||||
next.reset();
|
||||
|
||||
const action = ac.SendToContent({type: "FOO"}, 123);
|
||||
const action = ac.AlsoToOneContent({type: "FOO"}, 123);
|
||||
rehydrationMiddleware(store)(next)(action);
|
||||
assert.calledWith(next, action);
|
||||
});
|
||||
@ -125,7 +140,7 @@ describe("initStore", () => {
|
||||
assert.calledWith(next, action);
|
||||
});
|
||||
it("should allow action to main that does not belong to EARLY_QUEUED_ACTIONS to go through", () => {
|
||||
const action = ac.SendToMain({type: "FOO"});
|
||||
const action = ac.AlsoToMain({type: "FOO"});
|
||||
const next = sinon.spy();
|
||||
|
||||
queueEarlyMessageMiddleware(store)(next)(action);
|
||||
@ -136,8 +151,8 @@ describe("initStore", () => {
|
||||
EARLY_QUEUED_ACTIONS.forEach(actionType => {
|
||||
const testStore = initStore({number: addNumberReducer});
|
||||
const next = sinon.spy();
|
||||
const action = ac.SendToMain({type: actionType});
|
||||
const fromMainAction = ac.SendToContent({type: "FOO"}, 123);
|
||||
const action = ac.AlsoToMain({type: actionType});
|
||||
const fromMainAction = ac.AlsoToOneContent({type: "FOO"}, 123);
|
||||
|
||||
// Early actions should be added to the queue
|
||||
queueEarlyMessageMiddleware(testStore)(next)(action);
|
||||
|
@ -39,6 +39,10 @@ overrider.set({
|
||||
},
|
||||
isSuccessCode: () => true
|
||||
},
|
||||
ChromeUtils: {
|
||||
defineModuleGetter() {},
|
||||
import() {}
|
||||
},
|
||||
// eslint-disable-next-line object-shorthand
|
||||
ContentSearchUIController: function() {}, // NB: This is a function/constructor
|
||||
dump() {},
|
||||
@ -90,7 +94,10 @@ overrider.set({
|
||||
getVisibleEngines: () => [{identifier: "google"}, {identifier: "bing"}],
|
||||
defaultEngine: {identifier: "google"}
|
||||
},
|
||||
scriptSecurityManager: {getSystemPrincipal() {}}
|
||||
scriptSecurityManager: {
|
||||
createNullPrincipal() {},
|
||||
getSystemPrincipal() {}
|
||||
}
|
||||
},
|
||||
XPCOMUtils: {
|
||||
defineLazyGetter(_1, _2, f) { f(); },
|
||||
|
Loading…
Reference in New Issue
Block a user