From a90a5cba08fdf6c0ceb95101c275108a152a3aed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 12 Jun 2024 07:35:37 +0200 Subject: Merging upstream version 127.0. Signed-off-by: Daniel Baumann --- .../urlbar/ActionsProviderContextualSearch.sys.mjs | 121 +++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 browser/components/urlbar/ActionsProviderContextualSearch.sys.mjs (limited to 'browser/components/urlbar/ActionsProviderContextualSearch.sys.mjs') diff --git a/browser/components/urlbar/ActionsProviderContextualSearch.sys.mjs b/browser/components/urlbar/ActionsProviderContextualSearch.sys.mjs new file mode 100644 index 0000000000..58af7c94c5 --- /dev/null +++ b/browser/components/urlbar/ActionsProviderContextualSearch.sys.mjs @@ -0,0 +1,121 @@ +/* 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/. */ + +import { UrlbarUtils } from "resource:///modules/UrlbarUtils.sys.mjs"; + +import { + ActionsProvider, + ActionsResult, +} from "resource:///modules/ActionsProvider.sys.mjs"; + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + OpenSearchEngine: "resource://gre/modules/OpenSearchEngine.sys.mjs", + loadAndParseOpenSearchEngine: + "resource://gre/modules/OpenSearchLoader.sys.mjs", + UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs", + UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.sys.mjs", +}); + +const ENABLED_PREF = "contextualSearch.enabled"; + +/** + * A provider that returns an option for using the search engine provided + * by the active view if it utilizes OpenSearch. + */ +class ProviderContextualSearch extends ActionsProvider { + constructor() { + super(); + this.engines = new Map(); + } + + get name() { + return "ActionsProviderContextualSearch"; + } + + isActive(queryContext) { + return ( + queryContext.trimmedSearchString && + lazy.UrlbarPrefs.get(ENABLED_PREF) && + !queryContext.searchMode + ); + } + + async queryAction(queryContext, controller) { + let instance = this.queryInstance; + const hostname = URL.parse(queryContext.currentPage)?.hostname; + + // This happens on about pages, which won't have associated engines + if (!hostname) { + return null; + } + + let engine = await this.fetchEngine(controller); + let icon = engine?.icon || (await engine?.getIconURL?.()); + let defaultEngine = lazy.UrlbarSearchUtils.getDefaultEngine(); + + if ( + !engine || + engine.name === defaultEngine?.name || + instance != this.queryInstance + ) { + return null; + } + + return new ActionsResult({ + key: "contextual-search", + l10nId: "urlbar-result-search-with", + l10nArgs: { engine: engine.name || engine.title }, + icon, + }); + } + + async fetchEngine(controller) { + let browser = controller.browserWindow.gBrowser.selectedBrowser; + let hostname = browser?.currentURI.host; + + if (this.engines.has(hostname)) { + return this.engines.get(hostname); + } + + // Strip www. to allow for partial matches when looking for an engine. + const [host] = UrlbarUtils.stripPrefixAndTrim(hostname, { + stripWww: true, + }); + let engines = await lazy.UrlbarSearchUtils.enginesForDomainPrefix(host, { + matchAllDomainLevels: true, + }); + return engines[0] ?? browser?.engines?.[0]; + } + + async pickAction(queryContext, controller, element) { + // If we have an engine to add, first create a new OpenSearchEngine, then + // get and open a url to execute a search for the term in the url bar. + let engine = await this.fetchEngine(controller); + + if (engine.uri) { + let engineData = await lazy.loadAndParseOpenSearchEngine( + Services.io.newURI(engine.uri) + ); + engine = new lazy.OpenSearchEngine({ engineData }); + engine._setIcon(engine.icon, false); + } + + const [url] = UrlbarUtils.getSearchQueryUrl( + engine, + queryContext.searchString + ); + element.ownerGlobal.gBrowser.fixupAndLoadURIString(url, { + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), + }); + element.ownerGlobal.gBrowser.selectedBrowser.focus(); + } + + resetForTesting() { + this.engines = new Map(); + } +} + +export var ActionsProviderContextualSearch = new ProviderContextualSearch(); -- cgit v1.2.3