tor-browser

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

commit 9173a896c28f0bbc79887444f793281ef1899a4c
parent 2be29d8370b79f15355c84519e34b6bcfbcbffc0
Author: Irene Ni <ini@mozilla.com>
Date:   Mon,  8 Dec 2025 22:01:57 +0000

Bug 2004746 - Add URL normalization step for New Tab frecency based tile sorting. r=home-newtab-reviewers,nbarrett

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

Diffstat:
Mbrowser/extensions/newtab/lib/TopSitesFeed.sys.mjs | 19++++++++++++++++++-
Mbrowser/extensions/newtab/test/xpcshell/test_TopSitesFeed_frecencyRanking.js | 44++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/browser/extensions/newtab/lib/TopSitesFeed.sys.mjs b/browser/extensions/newtab/lib/TopSitesFeed.sys.mjs @@ -1449,6 +1449,19 @@ export class TopSitesFeed { ); } + normalizeUrl(url) { + let normalized = url; + if (normalized.startsWith("https://")) { + normalized = normalized.slice(8); + } else if (normalized.startsWith("http://")) { + normalized = normalized.slice(7); + } + if (normalized.startsWith("www.")) { + normalized = normalized.slice(4); + } + return normalized; + } + /** * Build frecency-boosted spocs from a list of sponsor domains by checking Places history. * Checks if domains exist in history, dedupes against organic topsites, @@ -1481,9 +1494,13 @@ export class TopSitesFeed { const candidates = []; frecent.forEach(site => { + const normalizedSiteUrl = this.normalizeUrl(site.url); + for (const domainObj of sponsorsToCheck) { + const normalizedDomain = this.normalizeUrl(domainObj.domain); + if ( - !site.url.startsWith(domainObj.domain) || + !normalizedSiteUrl.startsWith(normalizedDomain) || lazy.NewTabUtils.blockedLinks.isBlocked({ url: domainObj.domain }) ) { continue; diff --git a/browser/extensions/newtab/test/xpcshell/test_TopSitesFeed_frecencyRanking.js b/browser/extensions/newtab/test/xpcshell/test_TopSitesFeed_frecencyRanking.js @@ -108,6 +108,7 @@ function getTopSitesFeedForTest( return feed; } +// eslint-disable-next-line max-statements add_task(async function test_frecency_sponsored_topsites() { let sandbox = sinon.createSandbox(); { @@ -197,7 +198,7 @@ add_task(async function test_frecency_sponsored_topsites() { sandbox.restore(); } - /*{ + { info( "TopSitesFeed.fetchFrecencyBoostedSpocs - " + "Should return a single match with a subdomain" @@ -216,7 +217,7 @@ add_task(async function test_frecency_sponsored_topsites() { Assert.equal(frecencyBoostedSpocs[0].hostname, "hostname1"); sandbox.restore(); - }*/ + } { info( "TopSitesFeed.fetchFrecencyBoostedSpocs - " + @@ -266,4 +267,43 @@ add_task(async function test_frecency_sponsored_topsites() { sandbox.restore(); } + { + info( + "TopSitesFeed.fetchFrecencyBoostedSpocs - " + + "Should not return a match with a different subdomain" + ); + const feed = getTopSitesFeedForTest(sandbox, { + frecent: [ + { + url: "https://bus.domain1.com", + frecency: 1234, + }, + ], + }); + + const frecencyBoostedSpocs = await feed.fetchFrecencyBoostedSpocs(); + Assert.equal(frecencyBoostedSpocs.length, 0); + + sandbox.restore(); + } + { + info( + "TopSitesFeed.fetchFrecencyBoostedSpocs - " + + "Should return a match with the same subdomain" + ); + const feed = getTopSitesFeedForTest(sandbox, { + frecent: [ + { + url: "https://sub.domain1.com", + frecency: 1234, + }, + ], + }); + + const frecencyBoostedSpocs = await feed.fetchFrecencyBoostedSpocs(); + Assert.equal(frecencyBoostedSpocs.length, 1); + Assert.equal(frecencyBoostedSpocs[0].hostname, "hostname1sub"); + + sandbox.restore(); + } });