1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
/* 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 lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
});
/**
* Get the URLs with the top frecency scores.
*
* Note:
* - Blocked URLs are excluded
* - Allow multiple URLs from the same domain (www vs non-www urls)
*
* @param {number} maxUrls
* The maximum number of URLs to fetch.
* @param {number} frecencyThreshold
* The minimal frecency score of the URL. Will use the default set by
* the upstream module if unspecified. For reference, "100" means one
* visit in the past 3 days. see more details at:
* `/browser/components/urlbar/docs/ranking.rst`
* @returns {Array}
* An array of URLs. Note that the actual number could be less than `maxUrls`.
*/
export async function getTopFrecentUrls(
maxUrls,
frecencyThreshold /* for test */
) {
const options = {
ignoreBlocked: true,
onePerDomain: false,
includeFavicon: false,
topsiteFrecency: frecencyThreshold,
numItems: maxUrls,
};
const records = await lazy.NewTabUtils.activityStreamLinks.getTopSites(
options
);
return records.map(site => site.url);
}
/**
* Get the URLs of the most recent browsing history.
*
* Note:
* - Blocked URLs are excluded
* - Recent bookmarks are excluded
* - Recent "Save-to-Pocket" URLs are excluded
* - It would only return URLs if the page meta data is present. We can relax
* this in the future.
* - Multiple URLs may be returned for the same domain
*
* @param {number} maxUrls
* The maximum number of URLs to fetch.
* @returns {Array}
* An array of URLs. Note that the actual number could be less than `maxUrls`.
*/
export async function getMostRecentUrls(maxUrls) {
const options = {
ignoreBlocked: true,
excludeBookmarks: true,
excludeHistory: false,
excludePocket: true,
withFavicons: false,
numItems: maxUrls,
};
const records = await lazy.NewTabUtils.activityStreamLinks.getHighlights(
options
);
return records.map(site => site.url);
}
/**
* Get the URLs as a combination of the top frecent and the most recent
* browsing history.
*
* It will fetch `maxUrls` URLs from top frecent URLs and use most recent URLs
* as a fallback if the former is insufficient. Duplicates will be removed
* As a result, the returned URLs might be fewer than requested.
*
* @param {number} maxUrls
* The maximum number of URLs to fetch.
* @returns {Array}
* An array of URLs.
*/
export async function getFrecentRecentCombinedUrls(maxUrls) {
let urls = await getTopFrecentUrls(maxUrls);
if (urls.length < maxUrls) {
const n = Math.round((maxUrls - urls.length) * 1.2); // Over-fetch for deduping
const recentUrls = await getMostRecentUrls(n);
urls = dedupUrls(urls, recentUrls).slice(0, maxUrls);
}
return urls;
}
/**
* A helper to deduplicate items from any number of grouped URLs.
*
* Note:
* - Currently, all the elements (URLs) of the input arrays are treated as keys.
* - It doesn't assume the uniqueness within the group, therefore, in-group
* duplicates will be deduped as well.
*
* @param {Array} groups
* Contains an arbitrary number of arrays of URLs.
* @returns {Array}
* An array of unique URLs from the input groups.
*/
function dedupUrls(...groups) {
const uniques = new Set(groups.flat());
return [...uniques];
}
|