tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 2ac60a9b88badd3e893d90f59760189ea16ce056
parent 35da0b7f0f736cd63af13afb70fa4377b1faed69
Author: scottdowne <sdowne@mozilla.com>
Date:   Sat,  6 Dec 2025 00:26:18 +0000

Bug 2003855 - Newtab frecency-based sorting matching logic updates r=home-newtab-reviewers,nbarrett

Differential Revision: https://phabricator.services.mozilla.com/D275320

Diffstat:
Mbrowser/extensions/newtab/lib/TopSitesFeed.sys.mjs | 75++++++++++++++++++++++++++++++++++++++++++++-------------------------------
1 file changed, 44 insertions(+), 31 deletions(-)

diff --git a/browser/extensions/newtab/lib/TopSitesFeed.sys.mjs b/browser/extensions/newtab/lib/TopSitesFeed.sys.mjs @@ -113,6 +113,7 @@ const PREF_SOV_NAME = "sov.name"; const PREF_SOV_AMP_ALLOCATION = "sov.amp.allocation"; const PREF_SOV_FRECENCY_ALLOCATION = "sov.frecency.allocation"; const DEFAULT_SOV_SLOT_COUNT = 3; +const DEFAULT_SOV_NUM_ITEMS = 200; // Search experiment stuff const FILTER_DEFAULT_SEARCH_PREF = "improvesearch.noDefaultSearchTile"; @@ -1372,6 +1373,7 @@ export class TopSitesFeed { const sponsorData = { title, + domain, hostname, redirectURL: redirect_url, faviconDataURI, @@ -1418,8 +1420,14 @@ export class TopSitesFeed { * @returns {Array} Filtered list of sponsors not in organic topsites */ dedupeSponsorsAgainstTopsites(sponsors = []) { + const topSitesCount = + this.store.getState().Prefs.values[ROWS_PREF] * + TOP_SITES_MAX_SITES_PER_ROW; + + const linksWithDefaults = this._linksWithDefaults || []; const topsites = new Set( - (this._linksWithDefaults || []) + linksWithDefaults + .slice(0, topSitesCount) .filter(site => site.type !== "frecency-boost") .map(site => { try { @@ -1460,40 +1468,45 @@ export class TopSitesFeed { return []; } - let pagesMap; - try { - pagesMap = await lazy.PlacesUtils.history.fetchMany( - sponsorsToCheck.map(({ hostname }) => `https://${hostname}`) - ); - } catch (error) { - lazy.log.warn(`Failed to fetch history data: ${error.message}`); - return []; - } + const { values } = this.store.getState().Prefs; + const numItems = + values?.trainhopConfig?.sov?.numItems || DEFAULT_SOV_NUM_ITEMS; + const topsiteFrecency = lazy.pageFrecencyThreshold; + + // Get all frecent sites from history. + const frecent = await this.frecentCache.request({ + numItems, + topsiteFrecency, + }); const candidates = []; - for (const domainObj of sponsorsToCheck) { - const url = `https://${domainObj.hostname}/`; - const page = pagesMap.get(url); + frecent.forEach(site => { + for (const domainObj of sponsorsToCheck) { + if ( + !site.url.startsWith(domainObj.domain) || + lazy.NewTabUtils.blockedLinks.isBlocked({ url: domainObj.domain }) + ) { + continue; + } - if (!page || lazy.NewTabUtils.blockedLinks.isBlocked({ url })) { - continue; - } + const sponsorData = this._frecencyBoostedSponsors.get( + domainObj.hostname + ); - const sponsorData = this._frecencyBoostedSponsors.get(domainObj.hostname); - - candidates.push({ - hostname: domainObj.hostname, - url: domainObj.redirectURL, - label: domainObj.title, - sponsored_position: 3, - partner: SPONSORED_TILE_PARTNER_FREC_BOOST, - type: "frecency-boost", - frecency: page.frecency, - show_sponsored_label: true, - favicon: sponsorData.faviconDataURI, - faviconSize: 96, - }); - } + candidates.push({ + hostname: domainObj.hostname, + url: domainObj.redirectURL, + label: domainObj.title, + sponsored_position: 3, + partner: SPONSORED_TILE_PARTNER_FREC_BOOST, + type: "frecency-boost", + frecency: site.frecency, + show_sponsored_label: true, + favicon: sponsorData.faviconDataURI, + faviconSize: 96, + }); + } + }); // If we have a matched set of candidates, // we can check if it's an exposure event.