Bug 1944416: Restore individual tabs from closed groups in closed windows r=dao,sessi...
[gecko.git] / browser / components / urlbar / UrlbarProviderRecentSearches.sys.mjs
blob4bf78b4ae70563b1592627c79ba3ac766483e1e4
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/. */
5 /**
6  * This module exports a provider returning the user's recent searches.
7  */
9 import {
10   UrlbarProvider,
11   UrlbarUtils,
12 } from "resource:///modules/UrlbarUtils.sys.mjs";
14 const lazy = {};
15 ChromeUtils.defineESModuleGetters(lazy, {
16   FormHistory: "resource://gre/modules/FormHistory.sys.mjs",
17   SearchUtils: "resource://gre/modules/SearchUtils.sys.mjs",
18   UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
19   UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs",
20   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.sys.mjs",
21 });
23 // These prefs are relative to the `browser.urlbar` branch.
24 const ENABLED_PREF = "recentsearches.featureGate";
25 const SUGGEST_PREF = "suggest.recentsearches";
26 const EXPIRATION_PREF = "recentsearches.expirationMs";
27 const LASTDEFAULTCHANGED_PREF = "recentsearches.lastDefaultChanged";
29 /**
30  * A provider that returns the Recent Searches performed by the user.
31  */
32 class ProviderRecentSearches extends UrlbarProvider {
33   constructor(...args) {
34     super(...args);
35     Services.obs.addObserver(this, lazy.SearchUtils.TOPIC_ENGINE_MODIFIED);
36   }
38   get name() {
39     return "RecentSearches";
40   }
42   get type() {
43     return UrlbarUtils.PROVIDER_TYPE.PROFILE;
44   }
46   isActive(queryContext) {
47     return (
48       lazy.UrlbarPrefs.get(ENABLED_PREF) &&
49       lazy.UrlbarPrefs.get(SUGGEST_PREF) &&
50       !queryContext.restrictSource &&
51       !queryContext.searchString &&
52       !queryContext.searchMode
53     );
54   }
56   /**
57    * We use the same priority as `UrlbarProviderTopSites` as these are both
58    * shown on an empty urlbar query.
59    *
60    * @returns {number} The provider's priority for the given query.
61    */
62   getPriority() {
63     return 1;
64   }
66   onEngagement(queryContext, controller, details) {
67     let { result } = details;
68     let engine = lazy.UrlbarSearchUtils.getDefaultEngine(
69       queryContext.isPrivate
70     );
72     if (details.selType == "dismiss" && queryContext.formHistoryName) {
73       lazy.FormHistory.update({
74         op: "remove",
75         fieldname: "searchbar-history",
76         value: result.payload.suggestion,
77         source: engine.name,
78       }).catch(error =>
79         console.error(`Removing form history failed: ${error}`)
80       );
81       controller.removeResult(result);
82     }
83   }
85   async startQuery(queryContext, addCallback) {
86     let engine = lazy.UrlbarSearchUtils.getDefaultEngine(
87       queryContext.isPrivate
88     );
89     if (!engine) {
90       return;
91     }
92     let results = await lazy.FormHistory.search(["value", "lastUsed"], {
93       fieldname: "searchbar-history",
94       source: engine.name,
95     });
97     let expiration = parseInt(lazy.UrlbarPrefs.get(EXPIRATION_PREF), 10);
98     let lastDefaultChanged = parseInt(
99       lazy.UrlbarPrefs.get(LASTDEFAULTCHANGED_PREF),
100       10
101     );
102     let now = Date.now();
104     // We only want to show searches since the last engine change, if we
105     // havent changed the engine we expire the display of the searches
106     // after a period of time.
107     if (lastDefaultChanged != -1) {
108       expiration = Math.min(expiration, now - lastDefaultChanged);
109     }
111     results = results.filter(
112       result => now - Math.floor(result.lastUsed / 1000) < expiration
113     );
114     results.sort((a, b) => b.lastUsed - a.lastUsed);
116     if (results.length > lazy.UrlbarPrefs.get("recentsearches.maxResults")) {
117       results.length = lazy.UrlbarPrefs.get("recentsearches.maxResults");
118     }
120     for (let result of results) {
121       let res = new lazy.UrlbarResult(
122         UrlbarUtils.RESULT_TYPE.SEARCH,
123         UrlbarUtils.RESULT_SOURCE.HISTORY,
124         {
125           engine: engine.name,
126           suggestion: result.value,
127           isBlockable: true,
128           blockL10n: { id: "urlbar-result-menu-remove-from-history" },
129           helpUrl:
130             Services.urlFormatter.formatURLPref("app.support.baseURL") +
131             "awesome-bar-result-menu",
132         }
133       );
134       addCallback(this, res);
135     }
136   }
138   observe(subject, topic, data) {
139     switch (data) {
140       case lazy.SearchUtils.MODIFIED_TYPE.DEFAULT:
141         lazy.UrlbarPrefs.set(LASTDEFAULTCHANGED_PREF, Date.now().toString());
142         break;
143     }
144   }
147 export var UrlbarProviderRecentSearches = new ProviderRecentSearches();