Bug 1942898 - Decouple UrlbarProviderTopSites.sys.mjs from Reducers.sys.mjs r=home-newtab-reviewers,urlbar-reviewers,mconley,jteow
Differential Revision: https://phabricator.services.mozilla.com/D235645
This commit is contained in:
@@ -5,8 +5,11 @@
|
|||||||
import { actionTypes as at } from "resource://activity-stream/common/Actions.mjs";
|
import { actionTypes as at } from "resource://activity-stream/common/Actions.mjs";
|
||||||
import { Dedupe } from "resource://activity-stream/common/Dedupe.sys.mjs";
|
import { Dedupe } from "resource://activity-stream/common/Dedupe.sys.mjs";
|
||||||
|
|
||||||
export const TOP_SITES_DEFAULT_ROWS = 1;
|
export {
|
||||||
export const TOP_SITES_MAX_SITES_PER_ROW = 8;
|
TOP_SITES_DEFAULT_ROWS,
|
||||||
|
TOP_SITES_MAX_SITES_PER_ROW,
|
||||||
|
} from "resource:///modules/topsites/constants.mjs";
|
||||||
|
|
||||||
const PREF_COLLECTION_DISMISSIBLE = "discoverystream.isCollectionDismissible";
|
const PREF_COLLECTION_DISMISSIBLE = "discoverystream.isCollectionDismissible";
|
||||||
|
|
||||||
const dedupe = new Dedupe(site => site && site.url);
|
const dedupe = new Dedupe(site => site && site.url);
|
||||||
@@ -174,43 +177,6 @@ function App(prevState = INITIAL_STATE.App, action) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* insertPinned - Inserts pinned links in their specified slots
|
|
||||||
*
|
|
||||||
* @param {array} a list of links
|
|
||||||
* @param {array} a list of pinned links
|
|
||||||
* @return {array} resulting list of links with pinned links inserted
|
|
||||||
*/
|
|
||||||
export function insertPinned(links, pinned) {
|
|
||||||
// Remove any pinned links
|
|
||||||
const pinnedUrls = pinned.map(link => link && link.url);
|
|
||||||
let newLinks = links.filter(link =>
|
|
||||||
link ? !pinnedUrls.includes(link.url) : false
|
|
||||||
);
|
|
||||||
newLinks = newLinks.map(link => {
|
|
||||||
if (link && link.isPinned) {
|
|
||||||
delete link.isPinned;
|
|
||||||
delete link.pinIndex;
|
|
||||||
}
|
|
||||||
return link;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Then insert them in their specified location
|
|
||||||
pinned.forEach((val, index) => {
|
|
||||||
if (!val) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let link = Object.assign({}, val, { isPinned: true, pinIndex: index });
|
|
||||||
if (index > newLinks.length) {
|
|
||||||
newLinks[index] = link;
|
|
||||||
} else {
|
|
||||||
newLinks.splice(index, 0, link);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return newLinks;
|
|
||||||
}
|
|
||||||
|
|
||||||
function TopSites(prevState = INITIAL_STATE.TopSites, action) {
|
function TopSites(prevState = INITIAL_STATE.TopSites, action) {
|
||||||
let hasMatch;
|
let hasMatch;
|
||||||
let newRows;
|
let newRows;
|
||||||
|
|||||||
@@ -6557,6 +6557,14 @@ class Dedupe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
;// CONCATENATED MODULE: ../topsites/constants.mjs
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
const TOP_SITES_DEFAULT_ROWS = 1;
|
||||||
|
const TOP_SITES_MAX_SITES_PER_ROW = 8;
|
||||||
|
|
||||||
;// CONCATENATED MODULE: ./common/Reducers.sys.mjs
|
;// CONCATENATED MODULE: ./common/Reducers.sys.mjs
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* 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
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -6565,8 +6573,8 @@ class Dedupe {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const TOP_SITES_DEFAULT_ROWS = 1;
|
|
||||||
const TOP_SITES_MAX_SITES_PER_ROW = 8;
|
|
||||||
const PREF_COLLECTION_DISMISSIBLE = "discoverystream.isCollectionDismissible";
|
const PREF_COLLECTION_DISMISSIBLE = "discoverystream.isCollectionDismissible";
|
||||||
|
|
||||||
const dedupe = new Dedupe(site => site && site.url);
|
const dedupe = new Dedupe(site => site && site.url);
|
||||||
@@ -6734,43 +6742,6 @@ function App(prevState = INITIAL_STATE.App, action) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* insertPinned - Inserts pinned links in their specified slots
|
|
||||||
*
|
|
||||||
* @param {array} a list of links
|
|
||||||
* @param {array} a list of pinned links
|
|
||||||
* @return {array} resulting list of links with pinned links inserted
|
|
||||||
*/
|
|
||||||
function insertPinned(links, pinned) {
|
|
||||||
// Remove any pinned links
|
|
||||||
const pinnedUrls = pinned.map(link => link && link.url);
|
|
||||||
let newLinks = links.filter(link =>
|
|
||||||
link ? !pinnedUrls.includes(link.url) : false
|
|
||||||
);
|
|
||||||
newLinks = newLinks.map(link => {
|
|
||||||
if (link && link.isPinned) {
|
|
||||||
delete link.isPinned;
|
|
||||||
delete link.pinIndex;
|
|
||||||
}
|
|
||||||
return link;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Then insert them in their specified location
|
|
||||||
pinned.forEach((val, index) => {
|
|
||||||
if (!val) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let link = Object.assign({}, val, { isPinned: true, pinIndex: index });
|
|
||||||
if (index > newLinks.length) {
|
|
||||||
newLinks[index] = link;
|
|
||||||
} else {
|
|
||||||
newLinks.splice(index, 0, link);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return newLinks;
|
|
||||||
}
|
|
||||||
|
|
||||||
function TopSites(prevState = INITIAL_STATE.TopSites, action) {
|
function TopSites(prevState = INITIAL_STATE.TopSites, action) {
|
||||||
let hasMatch;
|
let hasMatch;
|
||||||
let newRows;
|
let newRows;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { shortURL } from "resource://activity-stream/lib/ShortURL.sys.mjs";
|
|||||||
import {
|
import {
|
||||||
TOP_SITES_DEFAULT_ROWS,
|
TOP_SITES_DEFAULT_ROWS,
|
||||||
TOP_SITES_MAX_SITES_PER_ROW,
|
TOP_SITES_MAX_SITES_PER_ROW,
|
||||||
} from "resource://activity-stream/common/Reducers.sys.mjs";
|
} from "resource:///modules/topsites/constants.mjs";
|
||||||
import { Dedupe } from "resource://activity-stream/common/Dedupe.sys.mjs";
|
import { Dedupe } from "resource://activity-stream/common/Dedupe.sys.mjs";
|
||||||
|
|
||||||
const lazy = {};
|
const lazy = {};
|
||||||
|
|||||||
@@ -7,10 +7,8 @@ import {
|
|||||||
actionTypes as at,
|
actionTypes as at,
|
||||||
} from "resource://activity-stream/common/Actions.mjs";
|
} from "resource://activity-stream/common/Actions.mjs";
|
||||||
import { TippyTopProvider } from "resource:///modules/topsites/TippyTopProvider.sys.mjs";
|
import { TippyTopProvider } from "resource:///modules/topsites/TippyTopProvider.sys.mjs";
|
||||||
import {
|
import { insertPinned } from "resource:///modules/topsites/TopSites.sys.mjs";
|
||||||
insertPinned,
|
import { TOP_SITES_MAX_SITES_PER_ROW } from "resource:///modules/topsites/constants.mjs";
|
||||||
TOP_SITES_MAX_SITES_PER_ROW,
|
|
||||||
} from "resource://activity-stream/common/Reducers.sys.mjs";
|
|
||||||
import { Dedupe } from "resource://activity-stream/common/Dedupe.sys.mjs";
|
import { Dedupe } from "resource://activity-stream/common/Dedupe.sys.mjs";
|
||||||
import {
|
import {
|
||||||
shortURL,
|
shortURL,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { INITIAL_STATE, insertPinned, reducers } from "common/Reducers.sys.mjs";
|
import { INITIAL_STATE, reducers } from "common/Reducers.sys.mjs";
|
||||||
const {
|
const {
|
||||||
TopSites,
|
TopSites,
|
||||||
App,
|
App,
|
||||||
@@ -735,76 +735,6 @@ describe("Reducers", () => {
|
|||||||
assert.equal(oldRow, oldState[0].rows[1]);
|
assert.equal(oldRow, oldState[0].rows[1]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe("#insertPinned", () => {
|
|
||||||
let links;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
links = new Array(12).fill(null).map((v, i) => ({ url: `site${i}.com` }));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should place pinned links where they belong", () => {
|
|
||||||
const pinned = [
|
|
||||||
{ url: "http://github.com/mozilla/activity-stream", title: "moz/a-s" },
|
|
||||||
{ url: "http://example.com", title: "example" },
|
|
||||||
];
|
|
||||||
const result = insertPinned(links, pinned);
|
|
||||||
for (let index of [0, 1]) {
|
|
||||||
assert.equal(result[index].url, pinned[index].url);
|
|
||||||
assert.ok(result[index].isPinned);
|
|
||||||
assert.equal(result[index].pinIndex, index);
|
|
||||||
}
|
|
||||||
assert.deepEqual(result.slice(2), links);
|
|
||||||
});
|
|
||||||
it("should handle empty slots in the pinned list", () => {
|
|
||||||
const pinned = [
|
|
||||||
null,
|
|
||||||
{ url: "http://github.com/mozilla/activity-stream", title: "moz/a-s" },
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
{ url: "http://example.com", title: "example" },
|
|
||||||
];
|
|
||||||
const result = insertPinned(links, pinned);
|
|
||||||
for (let index of [1, 4]) {
|
|
||||||
assert.equal(result[index].url, pinned[index].url);
|
|
||||||
assert.ok(result[index].isPinned);
|
|
||||||
assert.equal(result[index].pinIndex, index);
|
|
||||||
}
|
|
||||||
result.splice(4, 1);
|
|
||||||
result.splice(1, 1);
|
|
||||||
assert.deepEqual(result, links);
|
|
||||||
});
|
|
||||||
it("should handle a pinned site past the end of the list of links", () => {
|
|
||||||
const pinned = [];
|
|
||||||
pinned[11] = {
|
|
||||||
url: "http://github.com/mozilla/activity-stream",
|
|
||||||
title: "moz/a-s",
|
|
||||||
};
|
|
||||||
const result = insertPinned([], pinned);
|
|
||||||
assert.equal(result[11].url, pinned[11].url);
|
|
||||||
assert.isTrue(result[11].isPinned);
|
|
||||||
assert.equal(result[11].pinIndex, 11);
|
|
||||||
});
|
|
||||||
it("should unpin previously pinned links no longer in the pinned list", () => {
|
|
||||||
const pinned = [];
|
|
||||||
links[2].isPinned = true;
|
|
||||||
links[2].pinIndex = 2;
|
|
||||||
const result = insertPinned(links, pinned);
|
|
||||||
assert.notProperty(result[2], "isPinned");
|
|
||||||
assert.notProperty(result[2], "pinIndex");
|
|
||||||
});
|
|
||||||
it("should handle a link present in both the links and pinned list", () => {
|
|
||||||
const pinned = [links[7]];
|
|
||||||
const result = insertPinned(links, pinned);
|
|
||||||
assert.equal(links.length, result.length);
|
|
||||||
});
|
|
||||||
it("should not modify the original data", () => {
|
|
||||||
const pinned = [{ url: "http://example.com" }];
|
|
||||||
|
|
||||||
insertPinned(links, pinned);
|
|
||||||
|
|
||||||
assert.equal(typeof pinned[0].isPinned, "undefined");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe("Pocket", () => {
|
describe("Pocket", () => {
|
||||||
it("should return INITIAL_STATE by default", () => {
|
it("should return INITIAL_STATE by default", () => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
|
|||||||
@@ -551,6 +551,9 @@ const TEST_GLOBAL = {
|
|||||||
removeExpirationFilter() {},
|
removeExpirationFilter() {},
|
||||||
},
|
},
|
||||||
Logger: FakeLogger,
|
Logger: FakeLogger,
|
||||||
|
LinksCache: class {},
|
||||||
|
FaviconFeed: class {},
|
||||||
|
|
||||||
getFxAccountsSingleton() {},
|
getFxAccountsSingleton() {},
|
||||||
AboutNewTab: {},
|
AboutNewTab: {},
|
||||||
Glean: {
|
Glean: {
|
||||||
|
|||||||
@@ -22,9 +22,8 @@ ChromeUtils.defineESModuleGetters(this, {
|
|||||||
Screenshots: "resource://activity-stream/lib/Screenshots.sys.mjs",
|
Screenshots: "resource://activity-stream/lib/Screenshots.sys.mjs",
|
||||||
Sampling: "resource://gre/modules/components-utils/Sampling.sys.mjs",
|
Sampling: "resource://gre/modules/components-utils/Sampling.sys.mjs",
|
||||||
SearchService: "resource://gre/modules/SearchService.sys.mjs",
|
SearchService: "resource://gre/modules/SearchService.sys.mjs",
|
||||||
TOP_SITES_DEFAULT_ROWS: "resource://activity-stream/common/Reducers.sys.mjs",
|
TOP_SITES_DEFAULT_ROWS: "resource:///modules/topsites/constants.mjs",
|
||||||
TOP_SITES_MAX_SITES_PER_ROW:
|
TOP_SITES_MAX_SITES_PER_ROW: "resource:///modules/topsites/constants.mjs",
|
||||||
"resource://activity-stream/common/Reducers.sys.mjs",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const FAKE_FAVICON = "data987";
|
const FAKE_FAVICON = "data987";
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ module.exports = (env = {}) => ({
|
|||||||
new RegExp("^resource://activity-stream/"),
|
new RegExp("^resource://activity-stream/"),
|
||||||
path.join(__dirname, "./"),
|
path.join(__dirname, "./"),
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
new RegExp("^resource:///modules/topsites/"),
|
||||||
|
path.join(__dirname, "../topsites/"),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
new webpack.BannerPlugin(
|
new webpack.BannerPlugin(
|
||||||
|
|||||||
@@ -3,15 +3,12 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import { TippyTopProvider } from "resource:///modules/topsites/TippyTopProvider.sys.mjs";
|
import { TippyTopProvider } from "resource:///modules/topsites/TippyTopProvider.sys.mjs";
|
||||||
import {
|
|
||||||
insertPinned,
|
|
||||||
TOP_SITES_MAX_SITES_PER_ROW,
|
|
||||||
} from "resource://activity-stream/common/Reducers.sys.mjs";
|
|
||||||
import { Dedupe } from "resource://activity-stream/common/Dedupe.sys.mjs";
|
import { Dedupe } from "resource://activity-stream/common/Dedupe.sys.mjs";
|
||||||
import {
|
import {
|
||||||
shortURL,
|
shortURL,
|
||||||
shortHostname,
|
shortHostname,
|
||||||
} from "resource://activity-stream/lib/ShortURL.sys.mjs";
|
} from "resource://activity-stream/lib/ShortURL.sys.mjs";
|
||||||
|
import { TOP_SITES_MAX_SITES_PER_ROW } from "resource:///modules/topsites/constants.mjs";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CUSTOM_SEARCH_SHORTCUTS,
|
CUSTOM_SEARCH_SHORTCUTS,
|
||||||
@@ -39,6 +36,7 @@ ChromeUtils.defineLazyGetter(lazy, "log", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const DEFAULT_TOP_SITES = [];
|
export const DEFAULT_TOP_SITES = [];
|
||||||
|
|
||||||
const FRECENCY_THRESHOLD = 100 + 1; // 1 visit (skip first-run/one-time pages)
|
const FRECENCY_THRESHOLD = 100 + 1; // 1 visit (skip first-run/one-time pages)
|
||||||
const MIN_FAVICON_SIZE = 96;
|
const MIN_FAVICON_SIZE = 96;
|
||||||
const PINNED_FAVICON_PROPS_TO_MIGRATE = [
|
const PINNED_FAVICON_PROPS_TO_MIGRATE = [
|
||||||
@@ -1088,4 +1086,41 @@ class _TopSites {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insertPinned - Inserts pinned links in their specified slots
|
||||||
|
*
|
||||||
|
* @param {Array} links list of links
|
||||||
|
* @param {Array} pinned list of pinned links
|
||||||
|
* @returns {Array} resulting list of links with pinned links inserted
|
||||||
|
*/
|
||||||
|
export function insertPinned(links, pinned) {
|
||||||
|
// Remove any pinned links
|
||||||
|
const pinnedUrls = pinned.map(link => link && link.url);
|
||||||
|
let newLinks = links.filter(link =>
|
||||||
|
link ? !pinnedUrls.includes(link.url) : false
|
||||||
|
);
|
||||||
|
newLinks = newLinks.map(link => {
|
||||||
|
if (link && link.isPinned) {
|
||||||
|
delete link.isPinned;
|
||||||
|
delete link.pinIndex;
|
||||||
|
}
|
||||||
|
return link;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Then insert them in their specified location
|
||||||
|
pinned.forEach((val, index) => {
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let link = Object.assign({}, val, { isPinned: true, pinIndex: index });
|
||||||
|
if (index > newLinks.length) {
|
||||||
|
newLinks[index] = link;
|
||||||
|
} else {
|
||||||
|
newLinks.splice(index, 0, link);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return newLinks;
|
||||||
|
}
|
||||||
|
|
||||||
export const TopSites = new _TopSites();
|
export const TopSites = new _TopSites();
|
||||||
|
|||||||
6
browser/components/topsites/constants.mjs
Normal file
6
browser/components/topsites/constants.mjs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
export const TOP_SITES_DEFAULT_ROWS = 1;
|
||||||
|
export const TOP_SITES_MAX_SITES_PER_ROW = 8;
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
EXTRA_JS_MODULES.topsites += [
|
EXTRA_JS_MODULES.topsites += [
|
||||||
|
"constants.mjs",
|
||||||
"TippyTopProvider.sys.mjs",
|
"TippyTopProvider.sys.mjs",
|
||||||
"TopSites.sys.mjs",
|
"TopSites.sys.mjs",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { TopSites, DEFAULT_TOP_SITES } = ChromeUtils.importESModule(
|
const { TopSites, insertPinned, DEFAULT_TOP_SITES } =
|
||||||
"resource:///modules/topsites/TopSites.sys.mjs"
|
ChromeUtils.importESModule("resource:///modules/topsites/TopSites.sys.mjs");
|
||||||
);
|
|
||||||
|
|
||||||
const { actionTypes: at } = ChromeUtils.importESModule(
|
const { actionTypes: at } = ChromeUtils.importESModule(
|
||||||
"resource://activity-stream/common/Actions.mjs"
|
"resource://activity-stream/common/Actions.mjs"
|
||||||
@@ -22,9 +21,8 @@ ChromeUtils.defineESModuleGetters(this, {
|
|||||||
Screenshots: "resource://activity-stream/lib/Screenshots.sys.mjs",
|
Screenshots: "resource://activity-stream/lib/Screenshots.sys.mjs",
|
||||||
SearchService: "resource://gre/modules/SearchService.sys.mjs",
|
SearchService: "resource://gre/modules/SearchService.sys.mjs",
|
||||||
TestUtils: "resource://testing-common/TestUtils.sys.mjs",
|
TestUtils: "resource://testing-common/TestUtils.sys.mjs",
|
||||||
TOP_SITES_DEFAULT_ROWS: "resource://activity-stream/common/Reducers.sys.mjs",
|
TOP_SITES_DEFAULT_ROWS: "resource:///modules/topsites/constants.mjs",
|
||||||
TOP_SITES_MAX_SITES_PER_ROW:
|
TOP_SITES_MAX_SITES_PER_ROW: "resource:///modules/topsites/constants.mjs",
|
||||||
"resource://activity-stream/common/Reducers.sys.mjs",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const FAKE_FAVICON = "data987";
|
const FAKE_FAVICON = "data987";
|
||||||
@@ -2504,3 +2502,99 @@ add_task(async function test_updatePinnedSearchShortcuts() {
|
|||||||
|
|
||||||
sandbox.restore();
|
sandbox.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(async function test_insertPinned() {
|
||||||
|
info("#insertPinned");
|
||||||
|
|
||||||
|
function createLinks(count) {
|
||||||
|
return new Array(count).fill(null).map((v, i) => ({ url: `site${i}.com` }));
|
||||||
|
}
|
||||||
|
|
||||||
|
info("should place pinned links where they belong");
|
||||||
|
{
|
||||||
|
let links = createLinks(12);
|
||||||
|
const pinned = [
|
||||||
|
{ url: "http://github.com/mozilla/activity-stream", title: "moz/a-s" },
|
||||||
|
{ url: "http://example.com", title: "example" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const result = insertPinned(links, pinned);
|
||||||
|
for (let index of [0, 1]) {
|
||||||
|
Assert.equal(result[index].url, pinned[index].url, "Pinned URL matches");
|
||||||
|
Assert.ok(result[index].isPinned, "Link is marked as pinned");
|
||||||
|
Assert.equal(result[index].pinIndex, index, "Pin index is correct");
|
||||||
|
}
|
||||||
|
Assert.deepEqual(result.slice(2), links, "Remaining links are unchanged");
|
||||||
|
}
|
||||||
|
|
||||||
|
info("should handle empty slots in the pinned list");
|
||||||
|
{
|
||||||
|
let links = createLinks(12);
|
||||||
|
const pinned = [
|
||||||
|
null,
|
||||||
|
{ url: "http://github.com/mozilla/activity-stream", title: "moz/a-s" },
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
{ url: "http://example.com", title: "example" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const result = insertPinned(links, pinned);
|
||||||
|
for (let index of [1, 4]) {
|
||||||
|
Assert.equal(result[index].url, pinned[index].url, "Pinned URL matches");
|
||||||
|
Assert.ok(result[index].isPinned, "Link is marked as pinned");
|
||||||
|
Assert.equal(result[index].pinIndex, index, "Pin index is correct");
|
||||||
|
}
|
||||||
|
result.splice(4, 1);
|
||||||
|
result.splice(1, 1);
|
||||||
|
Assert.deepEqual(result, links, "Remaining links are unchanged");
|
||||||
|
}
|
||||||
|
|
||||||
|
info("should handle a pinned site past the end of the list of links");
|
||||||
|
{
|
||||||
|
const pinned = [];
|
||||||
|
pinned[11] = {
|
||||||
|
url: "http://github.com/mozilla/activity-stream",
|
||||||
|
title: "moz/a-s",
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = insertPinned([], pinned);
|
||||||
|
Assert.equal(result[11].url, pinned[11].url, "Pinned URL matches");
|
||||||
|
Assert.ok(result[11].isPinned, "Link is marked as pinned");
|
||||||
|
Assert.equal(result[11].pinIndex, 11, "Pin index is correct");
|
||||||
|
}
|
||||||
|
|
||||||
|
info("should unpin previously pinned links no longer in the pinned list");
|
||||||
|
{
|
||||||
|
let links = createLinks(12);
|
||||||
|
const pinned = [];
|
||||||
|
links[2].isPinned = true;
|
||||||
|
links[2].pinIndex = 2;
|
||||||
|
|
||||||
|
const result = insertPinned(links, pinned);
|
||||||
|
Assert.ok(!result[2].isPinned, "isPinned property removed");
|
||||||
|
Assert.ok(!result[2].pinIndex, "pinIndex property removed");
|
||||||
|
}
|
||||||
|
|
||||||
|
info("should handle a link present in both the links and pinned list");
|
||||||
|
{
|
||||||
|
let links = createLinks(12);
|
||||||
|
const pinned = [links[7]];
|
||||||
|
|
||||||
|
const result = insertPinned(links, pinned);
|
||||||
|
Assert.equal(links.length, result.length, "Length of links is unchanged");
|
||||||
|
}
|
||||||
|
|
||||||
|
info("should not modify the original data");
|
||||||
|
{
|
||||||
|
let links = createLinks(12);
|
||||||
|
const pinned = [{ url: "http://example.com" }];
|
||||||
|
|
||||||
|
insertPinned(links, pinned);
|
||||||
|
|
||||||
|
Assert.equal(
|
||||||
|
typeof pinned[0].isPinned,
|
||||||
|
"undefined",
|
||||||
|
"Pinned data is not mutated"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -19,9 +19,8 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
|||||||
AboutNewTab: "resource:///modules/AboutNewTab.sys.mjs",
|
AboutNewTab: "resource:///modules/AboutNewTab.sys.mjs",
|
||||||
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
|
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
|
||||||
TopSites: "resource:///modules/topsites/TopSites.sys.mjs",
|
TopSites: "resource:///modules/topsites/TopSites.sys.mjs",
|
||||||
TOP_SITES_DEFAULT_ROWS: "resource://activity-stream/common/Reducers.sys.mjs",
|
TOP_SITES_DEFAULT_ROWS: "resource:///modules/topsites/constants.mjs",
|
||||||
TOP_SITES_MAX_SITES_PER_ROW:
|
TOP_SITES_MAX_SITES_PER_ROW: "resource:///modules/topsites/constants.mjs",
|
||||||
"resource://activity-stream/common/Reducers.sys.mjs",
|
|
||||||
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
|
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
|
||||||
UrlbarProviderOpenTabs: "resource:///modules/UrlbarProviderOpenTabs.sys.mjs",
|
UrlbarProviderOpenTabs: "resource:///modules/UrlbarProviderOpenTabs.sys.mjs",
|
||||||
UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs",
|
UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs",
|
||||||
@@ -158,7 +157,7 @@ class ProviderTopSites extends UrlbarProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is done here, rather than in the global scope, because
|
// This is done here, rather than in the global scope, because
|
||||||
// TOP_SITES_DEFAULT_ROWS causes the import of Reducers.sys.mjs, and we want to
|
// TOP_SITES_DEFAULT_ROWS causes import of topsites constants.mjs, and we want to
|
||||||
// do that only when actually querying for Top Sites.
|
// do that only when actually querying for Top Sites.
|
||||||
if (this.topSitesRows === undefined) {
|
if (this.topSitesRows === undefined) {
|
||||||
XPCOMUtils.defineLazyPreferenceGetter(
|
XPCOMUtils.defineLazyPreferenceGetter(
|
||||||
|
|||||||
Reference in New Issue
Block a user