TippyTopProvider.sys.mjs (1916B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 const TIPPYTOP_PATH = "chrome://activity-stream/content/data/content/tippytop/"; 6 const TIPPYTOP_JSON_PATH = 7 "chrome://activity-stream/content/data/content/tippytop/top_sites.json"; 8 9 /* 10 * Get a domain from a url optionally stripping subdomains. 11 */ 12 export function getDomain(url, strip = "www.") { 13 let domain = URL.parse(url)?.hostname; 14 if (!domain) { 15 return ""; 16 } 17 if (strip === "*") { 18 try { 19 domain = Services.eTLD.getBaseDomainFromHost(domain); 20 } catch (ex) {} 21 } else if (domain.startsWith(strip)) { 22 domain = domain.slice(strip.length); 23 } 24 return domain; 25 } 26 27 export class TippyTopProvider { 28 constructor() { 29 this._sitesByDomain = new Map(); 30 this.initialized = false; 31 } 32 33 async init() { 34 // Load the Tippy Top sites from the json manifest. 35 try { 36 for (const site of await ( 37 await this.fetch(TIPPYTOP_JSON_PATH, { 38 credentials: "omit", 39 }) 40 ).json()) { 41 for (const domain of site.domains) { 42 this._sitesByDomain.set(domain, site); 43 } 44 } 45 this.initialized = true; 46 } catch (error) { 47 console.error("Failed to load tippy top manifest."); 48 } 49 } 50 51 processSite(site, strip) { 52 const tippyTop = this._sitesByDomain.get(getDomain(site.url, strip)); 53 if (tippyTop) { 54 site.tippyTopIcon = TIPPYTOP_PATH + tippyTop.image_url; 55 site.smallFavicon = TIPPYTOP_PATH + tippyTop.favicon_url; 56 site.backgroundColor = tippyTop.background_color; 57 } 58 return site; 59 } 60 61 /** 62 * This thin wrapper around global.fetch makes it easier for us to write 63 * automated tests that simulate responses from this fetch. 64 */ 65 fetch(...args) { 66 return fetch(...args); 67 } 68 }