mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1922570 - Show global actions on seperate row from heuristic. r=daisuke,desktop-theme-reviewers,urlbar-reviewers,dao
Differential Revision: https://phabricator.services.mozilla.com/D225051
This commit is contained in:
parent
c281f85c81
commit
492d53d62e
@ -436,6 +436,7 @@ pref("browser.urlbar.suggest.topsites", true);
|
||||
pref("browser.urlbar.suggest.engines", true);
|
||||
pref("browser.urlbar.suggest.calculator", false);
|
||||
pref("browser.urlbar.suggest.recentsearches", true);
|
||||
pref("browser.urlbar.suggest.quickactions", true);
|
||||
|
||||
pref("browser.urlbar.deduplication.enabled", false);
|
||||
pref("browser.urlbar.deduplication.thresholdDays", 7);
|
||||
|
@ -30,6 +30,7 @@ Preferences.addAll([
|
||||
{ id: "browser.urlbar.trending.featureGate", type: "bool" },
|
||||
{ id: "browser.urlbar.recentsearches.featureGate", type: "bool" },
|
||||
{ id: "browser.urlbar.suggest.recentsearches", type: "bool" },
|
||||
{ id: "browser.urlbar.scotchBonnet.enableOverride", type: "bool" },
|
||||
]);
|
||||
|
||||
const ENGINE_FLAVOR = "text/x-moz-search-engine";
|
||||
@ -446,8 +447,13 @@ var gSearchPane = {
|
||||
|
||||
_initQuickActionsSection() {
|
||||
let showPref = Preferences.get("browser.urlbar.quickactions.showPrefs");
|
||||
let scotchBonnet = Preferences.get(
|
||||
"browser.urlbar.scotchBonnet.enableOverride"
|
||||
);
|
||||
let showQuickActionsGroup = () => {
|
||||
document.getElementById("quickActionsBox").hidden = !showPref.value;
|
||||
document.getElementById("quickActionsBox").hidden = !(
|
||||
showPref.value || scotchBonnet.value
|
||||
);
|
||||
};
|
||||
showPref.on("change", showQuickActionsGroup);
|
||||
showQuickActionsGroup();
|
||||
|
@ -13,10 +13,7 @@ ChromeUtils.defineESModuleGetters(this, {
|
||||
|
||||
add_setup(async function setup() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.urlbar.secondaryActions.featureGate", true],
|
||||
["browser.urlbar.quickactions.enabled", true],
|
||||
],
|
||||
set: [["browser.urlbar.secondaryActions.featureGate", true]],
|
||||
});
|
||||
|
||||
ActionsProviderQuickActions.addAction("testaction", {
|
||||
|
@ -33,10 +33,10 @@ export class ActionsProvider {
|
||||
*
|
||||
* @param {UrlbarQueryContext} _queryContext The query context object.
|
||||
* @param {UrlbarController} _controller The urlbar controller.
|
||||
* @returns {ActionsResult}
|
||||
* @returns {Array} An array of ActionResult's
|
||||
* @abstract
|
||||
*/
|
||||
async queryAction(_queryContext, _controller) {
|
||||
async queryActions(_queryContext, _controller) {
|
||||
throw new Error("Not implemented.");
|
||||
}
|
||||
|
||||
@ -64,6 +64,7 @@ export class ActionsResult {
|
||||
#l10nArgs;
|
||||
#icon;
|
||||
#dataset;
|
||||
#onPick;
|
||||
|
||||
/**
|
||||
* @param {object} options
|
||||
@ -79,13 +80,16 @@ export class ActionsResult {
|
||||
* @param {object} options.dataset
|
||||
* An object of properties we set on the action button that
|
||||
* can be used to pass data when it is selected.
|
||||
* @param { Function} options.onPick
|
||||
* A callback function called when the result has been picked.
|
||||
*/
|
||||
constructor({ key, l10nId, l10nArgs, icon, dataset }) {
|
||||
constructor({ key, l10nId, l10nArgs, icon, dataset, onPick }) {
|
||||
this.#key = key;
|
||||
this.#l10nId = l10nId;
|
||||
this.#l10nArgs = l10nArgs;
|
||||
this.#icon = icon;
|
||||
this.#dataset = dataset;
|
||||
this.#onPick = onPick;
|
||||
}
|
||||
|
||||
get key() {
|
||||
@ -107,4 +111,8 @@ export class ActionsResult {
|
||||
get dataset() {
|
||||
return this.#dataset;
|
||||
}
|
||||
|
||||
get onPick() {
|
||||
return this.#onPick;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
const lazy = {};
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs",
|
||||
OpenSearchEngine: "resource://gre/modules/OpenSearchEngine.sys.mjs",
|
||||
loadAndParseOpenSearchEngine:
|
||||
"resource://gre/modules/OpenSearchLoader.sys.mjs",
|
||||
@ -43,7 +44,7 @@ class ProviderContextualSearch extends ActionsProvider {
|
||||
);
|
||||
}
|
||||
|
||||
async queryAction(queryContext, controller) {
|
||||
async queryActions(queryContext) {
|
||||
let instance = this.queryInstance;
|
||||
const hostname = URL.parse(queryContext.currentPage)?.hostname;
|
||||
|
||||
@ -52,7 +53,7 @@ class ProviderContextualSearch extends ActionsProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
let engine = await this.fetchEngine(controller);
|
||||
let engine = await this.fetchEngine();
|
||||
let icon = engine?.icon || (await engine?.getIconURL?.());
|
||||
let defaultEngine = lazy.UrlbarSearchUtils.getDefaultEngine();
|
||||
|
||||
@ -64,16 +65,22 @@ class ProviderContextualSearch extends ActionsProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ActionsResult({
|
||||
key: "contextual-search",
|
||||
l10nId: "urlbar-result-search-with",
|
||||
l10nArgs: { engine: engine.name || engine.title },
|
||||
icon,
|
||||
});
|
||||
return [
|
||||
new ActionsResult({
|
||||
key: "contextual-search",
|
||||
l10nId: "urlbar-result-search-with",
|
||||
l10nArgs: { engine: engine.name || engine.title },
|
||||
icon,
|
||||
onPick: (context, controller) => {
|
||||
this.pickAction(context, controller);
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
async fetchEngine(controller) {
|
||||
let browser = controller.browserWindow.gBrowser.selectedBrowser;
|
||||
async fetchEngine() {
|
||||
let browser =
|
||||
lazy.BrowserWindowTracker.getTopWindow().gBrowser.selectedBrowser;
|
||||
let hostname = browser?.currentURI.host;
|
||||
|
||||
if (this.engines.has(hostname)) {
|
||||
@ -90,8 +97,8 @@ class ProviderContextualSearch extends ActionsProvider {
|
||||
return engines[0] ?? browser?.engines?.[0];
|
||||
}
|
||||
|
||||
async pickAction(queryContext, controller, _element) {
|
||||
let engine = await this.fetchEngine(controller);
|
||||
async pickAction(queryContext, controller) {
|
||||
let engine = await this.fetchEngine();
|
||||
let enterSeachMode = true;
|
||||
|
||||
if (engine.uri && !queryContext.private) {
|
||||
|
@ -15,7 +15,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
});
|
||||
|
||||
// These prefs are relative to the `browser.urlbar` branch.
|
||||
const ENABLED_PREF = "quickactions.enabled";
|
||||
const ENABLED_PREF = "suggest.quickactions";
|
||||
const MATCH_IN_PHRASE_PREF = "quickactions.matchInPhrase";
|
||||
const MIN_SEARCH_PREF = "quickactions.minimumSearchString";
|
||||
|
||||
@ -29,7 +29,7 @@ class ProviderQuickActions extends ActionsProvider {
|
||||
|
||||
isActive(queryContext) {
|
||||
return (
|
||||
lazy.UrlbarPrefs.getScotchBonnetPref(ENABLED_PREF) &&
|
||||
lazy.UrlbarPrefs.get(ENABLED_PREF) &&
|
||||
!queryContext.searchMode &&
|
||||
queryContext.trimmedSearchString.length < 50 &&
|
||||
queryContext.trimmedSearchString.length >=
|
||||
@ -37,7 +37,7 @@ class ProviderQuickActions extends ActionsProvider {
|
||||
);
|
||||
}
|
||||
|
||||
async queryAction(queryContext) {
|
||||
async queryActions(queryContext) {
|
||||
let input = queryContext.trimmedLowerCaseSearchString;
|
||||
let results = await this.getActions(input);
|
||||
|
||||
@ -59,15 +59,18 @@ class ProviderQuickActions extends ActionsProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
let action = this.#actions.get(results[0]);
|
||||
return new ActionsResult({
|
||||
key: results[0],
|
||||
l10nId: action.label,
|
||||
icon: action.icon,
|
||||
dataset: {
|
||||
action: results[0],
|
||||
inputLength: queryContext.trimmedSearchString.length,
|
||||
},
|
||||
return results.map(key => {
|
||||
let action = this.#actions.get(key);
|
||||
return new ActionsResult({
|
||||
key,
|
||||
l10nId: action.label,
|
||||
icon: action.icon,
|
||||
dataset: {
|
||||
action: key,
|
||||
inputLength: queryContext.trimmedSearchString.length,
|
||||
},
|
||||
onPick: action.onPick,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1046,6 +1046,7 @@ class TelemetryEvent {
|
||||
.join(",");
|
||||
let actions = currentResults
|
||||
.map((r, i) => lazy.UrlbarUtils.searchEngagementTelemetryAction(r, i))
|
||||
.filter(v => v)
|
||||
.join(",");
|
||||
const search_engine_default_id = Services.search.defaultEngine.telemetryId;
|
||||
|
||||
|
@ -27,9 +27,6 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
|
||||
UrlbarQueryContext: "resource:///modules/UrlbarUtils.sys.mjs",
|
||||
UrlbarProviderOpenTabs: "resource:///modules/UrlbarProviderOpenTabs.sys.mjs",
|
||||
UrlbarProvidersManager: "resource:///modules/UrlbarProvidersManager.sys.mjs",
|
||||
UrlbarProviderActionsSearchMode:
|
||||
"resource:///modules/UrlbarProviderActionsSearchMode.sys.mjs",
|
||||
UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.sys.mjs",
|
||||
UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.sys.mjs",
|
||||
UrlbarUtils: "resource:///modules/UrlbarUtils.sys.mjs",
|
||||
@ -984,26 +981,6 @@ export class UrlbarInput {
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
element?.dataset.action &&
|
||||
element?.dataset.action != "tabswitch" &&
|
||||
result.providerName != lazy.UrlbarProviderActionsSearchMode.name
|
||||
) {
|
||||
this.controller.engagementEvent.record(event, {
|
||||
result,
|
||||
element,
|
||||
searchString: this._lastSearchString,
|
||||
selType: "action",
|
||||
searchSource: this.getSearchSource(event),
|
||||
});
|
||||
this.view.close();
|
||||
let provider = lazy.UrlbarProvidersManager.getActionProvider(
|
||||
element.dataset.providerName
|
||||
);
|
||||
let { queryContext } = this.controller._lastQueryContextWrapper || {};
|
||||
provider.pickAction(queryContext, this.controller, element);
|
||||
return;
|
||||
}
|
||||
this.pickResult(result, event, element);
|
||||
}
|
||||
|
||||
|
147
browser/components/urlbar/UrlbarProviderGlobalActions.sys.mjs
Normal file
147
browser/components/urlbar/UrlbarProviderGlobalActions.sys.mjs
Normal file
@ -0,0 +1,147 @@
|
||||
/* 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/. */
|
||||
|
||||
/**
|
||||
* This module exports a provider that returns all the available
|
||||
* global actions for a query.
|
||||
*/
|
||||
|
||||
import {
|
||||
UrlbarProvider,
|
||||
UrlbarUtils,
|
||||
} from "resource:///modules/UrlbarUtils.sys.mjs";
|
||||
|
||||
const lazy = {};
|
||||
|
||||
// Default icon shown for actions if no custom one is provided.
|
||||
const DEFAULT_ICON = "chrome://global/skin/icons/settings.svg";
|
||||
const DYNAMIC_TYPE_NAME = "actions";
|
||||
|
||||
// The suggestion index of the actions row within the urlbar results.
|
||||
const SUGGESTED_INDEX = 1;
|
||||
|
||||
const SCOTCH_BONNET_PREF = "scotchBonnet.enableOverride";
|
||||
const ACTIONS_PREF = "secondaryActions.featureGate";
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
|
||||
UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs",
|
||||
});
|
||||
|
||||
import { ActionsProviderQuickActions } from "resource:///modules/ActionsProviderQuickActions.sys.mjs";
|
||||
import { ActionsProviderContextualSearch } from "resource:///modules/ActionsProviderContextualSearch.sys.mjs";
|
||||
|
||||
let globalActionsProviders = [
|
||||
ActionsProviderContextualSearch,
|
||||
ActionsProviderQuickActions,
|
||||
];
|
||||
|
||||
/**
|
||||
* A provider that lets the user view all available global actions for a query.
|
||||
*/
|
||||
class ProviderGlobalActions extends UrlbarProvider {
|
||||
// A Map of the last queried actions.
|
||||
#actions = new Map();
|
||||
|
||||
get name() {
|
||||
return "UrlbarProviderGlobalActions";
|
||||
}
|
||||
|
||||
get type() {
|
||||
return UrlbarUtils.PROVIDER_TYPE.PROFILE;
|
||||
}
|
||||
|
||||
isActive() {
|
||||
return (
|
||||
lazy.UrlbarPrefs.get(SCOTCH_BONNET_PREF) ||
|
||||
lazy.UrlbarPrefs.get(ACTIONS_PREF)
|
||||
);
|
||||
}
|
||||
|
||||
async startQuery(queryContext, addCallback) {
|
||||
this.#actions.clear();
|
||||
|
||||
for (let provider of globalActionsProviders) {
|
||||
if (provider.isActive(queryContext)) {
|
||||
for (let action of (await provider.queryActions(queryContext)) || []) {
|
||||
this.#actions.set(action.key, action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.#actions.size) {
|
||||
return;
|
||||
}
|
||||
|
||||
let result = new lazy.UrlbarResult(
|
||||
UrlbarUtils.RESULT_TYPE.DYNAMIC,
|
||||
UrlbarUtils.RESULT_SOURCE.ACTIONS,
|
||||
{
|
||||
results: [...this.#actions.keys()],
|
||||
dynamicType: DYNAMIC_TYPE_NAME,
|
||||
inputLength: queryContext.searchString.length,
|
||||
}
|
||||
);
|
||||
result.suggestedIndex = SUGGESTED_INDEX;
|
||||
addCallback(this, result);
|
||||
}
|
||||
|
||||
onEngagement(queryContext, controller, details) {
|
||||
let key = details.element.dataset.action;
|
||||
let options = this.#actions.get(key).onPick(queryContext, controller);
|
||||
if (options?.focusContent) {
|
||||
details.element.ownerGlobal.gBrowser.selectedBrowser.focus();
|
||||
}
|
||||
controller.view.close();
|
||||
}
|
||||
|
||||
getViewTemplate(result) {
|
||||
return {
|
||||
children: [
|
||||
{
|
||||
name: "buttons",
|
||||
tag: "div",
|
||||
children: result.payload.results.map((key, i) => {
|
||||
let action = this.#actions.get(key);
|
||||
return {
|
||||
name: `button-${i}`,
|
||||
tag: "span",
|
||||
classList: ["urlbarView-action-btn"],
|
||||
attributes: {
|
||||
inputLength: result.payload.inputLength,
|
||||
"data-action": key,
|
||||
role: "button",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
tag: "img",
|
||||
attributes: {
|
||||
src: action.icon || DEFAULT_ICON,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: `label-${i}`,
|
||||
tag: "span",
|
||||
},
|
||||
],
|
||||
};
|
||||
}),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
getViewUpdate(result) {
|
||||
let viewUpdate = {};
|
||||
result.payload.results.forEach((key, i) => {
|
||||
let action = this.#actions.get(key);
|
||||
viewUpdate[`label-${i}`] = {
|
||||
l10n: { id: action.l10nId, args: action.l10nArgs, cacheable: true },
|
||||
};
|
||||
});
|
||||
return viewUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
export var UrlbarProviderGlobalActions = new ProviderGlobalActions();
|
@ -33,6 +33,8 @@ var localProviderModules = {
|
||||
"resource:///modules/UrlbarProviderAboutPages.sys.mjs",
|
||||
UrlbarProviderActionsSearchMode:
|
||||
"resource:///modules/UrlbarProviderActionsSearchMode.sys.mjs",
|
||||
UrlbarProviderGlobalActions:
|
||||
"resource:///modules/UrlbarProviderGlobalActions.sys.mjs",
|
||||
UrlbarProviderAliasEngines:
|
||||
"resource:///modules/UrlbarProviderAliasEngines.sys.mjs",
|
||||
UrlbarProviderAutofill: "resource:///modules/UrlbarProviderAutofill.sys.mjs",
|
||||
@ -86,14 +88,6 @@ var localMuxerModules = {
|
||||
"resource:///modules/UrlbarMuxerUnifiedComplete.sys.mjs",
|
||||
};
|
||||
|
||||
import { ActionsProviderQuickActions } from "resource:///modules/ActionsProviderQuickActions.sys.mjs";
|
||||
import { ActionsProviderContextualSearch } from "resource:///modules/ActionsProviderContextualSearch.sys.mjs";
|
||||
|
||||
let globalActionsProviders = [
|
||||
ActionsProviderContextualSearch,
|
||||
ActionsProviderQuickActions,
|
||||
];
|
||||
|
||||
const DEFAULT_MUXER = "UnifiedComplete";
|
||||
|
||||
/**
|
||||
@ -207,17 +201,6 @@ class ProvidersManager {
|
||||
return this.providers.find(p => p.name == name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the provider with the given name.
|
||||
*
|
||||
* @param {string} name
|
||||
* The provider name.
|
||||
* @returns {UrlbarProvider} The provider.
|
||||
*/
|
||||
getActionProvider(name) {
|
||||
return globalActionsProviders.find(p => p.name == name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a muxer object with the manager.
|
||||
*
|
||||
@ -324,14 +307,6 @@ class ProvidersManager {
|
||||
// history and bookmarks even if search engines are not available.
|
||||
}
|
||||
|
||||
// All current global actions are currently memory lookups so it is safe to
|
||||
// wait on them.
|
||||
this.#globalAction = lazy.UrlbarPrefs.getScotchBonnetPref(
|
||||
"secondaryActions.featureGate"
|
||||
)
|
||||
? await this.pickGlobalAction(queryContext, controller)
|
||||
: null;
|
||||
|
||||
if (query.canceled) {
|
||||
return;
|
||||
}
|
||||
@ -511,25 +486,6 @@ class ProvidersManager {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#globalAction = null;
|
||||
|
||||
async pickGlobalAction(queryContext, controller) {
|
||||
for (let provider of globalActionsProviders) {
|
||||
if (provider.isActive(queryContext)) {
|
||||
let action = await provider.queryAction(queryContext, controller);
|
||||
if (action) {
|
||||
action.providerName = provider.name;
|
||||
return action;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getGlobalAction() {
|
||||
return this.#globalAction;
|
||||
}
|
||||
}
|
||||
|
||||
export var UrlbarProvidersManager = new ProvidersManager();
|
||||
|
@ -1508,6 +1508,8 @@ export var UrlbarUtils = {
|
||||
return "fxsuggest_data_sharing_opt_in";
|
||||
case "Weather":
|
||||
return "weather";
|
||||
case "UrlbarProviderGlobalActions":
|
||||
return "action";
|
||||
}
|
||||
break;
|
||||
case UrlbarUtils.RESULT_TYPE.KEYWORD:
|
||||
@ -1605,13 +1607,11 @@ export var UrlbarUtils = {
|
||||
return "unknown";
|
||||
},
|
||||
|
||||
searchEngagementTelemetryAction(result, index) {
|
||||
let action =
|
||||
index == 0
|
||||
? lazy.UrlbarProvidersManager.getGlobalAction()
|
||||
: result.payload.action;
|
||||
|
||||
return action?.key ?? "none";
|
||||
searchEngagementTelemetryAction(result) {
|
||||
if (result.providerName != "UrlbarProviderGlobalActions") {
|
||||
return result.payload.action?.key ?? "none";
|
||||
}
|
||||
return result.payload.results.map(({ key }) => key).join(",");
|
||||
},
|
||||
|
||||
_getQuickSuggestTelemetryType(result) {
|
||||
|
@ -15,6 +15,8 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
ObjectUtils: "resource://gre/modules/ObjectUtils.sys.mjs",
|
||||
UrlbarProviderOpenTabs: "resource:///modules/UrlbarProviderOpenTabs.sys.mjs",
|
||||
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
|
||||
UrlbarProviderGlobalActions:
|
||||
"resource:///modules/UrlbarProviderGlobalActions.sys.mjs",
|
||||
UrlbarProviderQuickSuggest:
|
||||
"resource:///modules/UrlbarProviderQuickSuggest.sys.mjs",
|
||||
UrlbarProviderRecentSearches:
|
||||
@ -341,10 +343,18 @@ export class UrlbarView {
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.selectedRowIndex = Math.max(
|
||||
0,
|
||||
Math.min(end, selectedRowIndex + amount * (reverse ? -1 : 1))
|
||||
);
|
||||
|
||||
let index = Math.min(end, selectedRowIndex + amount * (reverse ? -1 : 1));
|
||||
// When navigating with arrow keys we skip rows that contain
|
||||
// global actions.
|
||||
if (
|
||||
this.#rows.children[index]?.result.providerName ==
|
||||
lazy.UrlbarProviderGlobalActions.name &&
|
||||
this.#rows.children.length > 2
|
||||
) {
|
||||
index = index + (reverse ? -1 : 1);
|
||||
}
|
||||
this.selectedRowIndex = Math.max(0, index);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1780,10 +1790,7 @@ export class UrlbarView {
|
||||
item._content.id = item.id + "-inner";
|
||||
|
||||
let isFirstChild = item === this.#rows.children[0];
|
||||
let secAction =
|
||||
result.heuristic || isFirstChild
|
||||
? lazy.UrlbarProvidersManager.getGlobalAction()
|
||||
: result.payload.action;
|
||||
let secAction = result.payload.action;
|
||||
let container = item.querySelector(".urlbarView-actions-container");
|
||||
if (secAction && !container) {
|
||||
item.appendChild(this.#createSecondaryAction(secAction, isFirstChild));
|
||||
|
@ -243,6 +243,7 @@ urlbar:
|
||||
description: >
|
||||
The type of the result the user selected. The `unknown` type should
|
||||
not occur and indicates a bug. The possible types are:
|
||||
`action`,
|
||||
`addon`,
|
||||
`autofill_about`,
|
||||
`autofill_adaptive`,
|
||||
@ -369,6 +370,7 @@ urlbar:
|
||||
Comma separated list of result types in the order they were shown to
|
||||
the user. The `unknown` type should not occur and indicates a bug. The
|
||||
possible types are:
|
||||
`action`,
|
||||
`addon`,
|
||||
`autofill_about`,
|
||||
`autofill_adaptive`,
|
||||
|
@ -31,6 +31,7 @@ EXTRA_JS_MODULES += [
|
||||
"UrlbarProviderBookmarkKeywords.sys.mjs",
|
||||
"UrlbarProviderCalculator.sys.mjs",
|
||||
"UrlbarProviderClipboard.sys.mjs",
|
||||
"UrlbarProviderGlobalActions.sys.mjs",
|
||||
"UrlbarProviderHeuristicFallback.sys.mjs",
|
||||
"UrlbarProviderHistoryUrlHeuristic.sys.mjs",
|
||||
"UrlbarProviderInputHistory.sys.mjs",
|
||||
|
@ -33,7 +33,7 @@ add_setup(async function setup() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.urlbar.quickactions.enabled", true],
|
||||
["browser.urlbar.secondaryActions.featureGate", true],
|
||||
["browser.urlbar.scotchBonnet.enableOverride", true],
|
||||
],
|
||||
});
|
||||
|
||||
@ -238,14 +238,14 @@ add_task(async function test_whitespace() {
|
||||
value: "",
|
||||
});
|
||||
const countForEmpty = window.document.querySelectorAll(
|
||||
".urlbarView-quickaction-button"
|
||||
".urlbarView-action-btn"
|
||||
).length;
|
||||
await UrlbarTestUtils.promiseAutocompleteResultPopup({
|
||||
window,
|
||||
value: " ",
|
||||
});
|
||||
const countForWhitespace = window.document.querySelectorAll(
|
||||
".urlbarView-quickaction-button"
|
||||
".urlbarView-action-btn"
|
||||
).length;
|
||||
Assert.equal(
|
||||
countForEmpty,
|
||||
|
@ -46,7 +46,7 @@ add_task(async function test_quickaction() {
|
||||
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getResultCount(window),
|
||||
1,
|
||||
2,
|
||||
"We matched the action"
|
||||
);
|
||||
|
||||
|
@ -170,9 +170,9 @@ add_task(async function general() {
|
||||
assert: () =>
|
||||
assertAbandonmentTelemetry([
|
||||
{
|
||||
groups: "heuristic,general",
|
||||
results: "search_engine,bookmark",
|
||||
n_results: 2,
|
||||
groups: "heuristic,suggested_index,general",
|
||||
results: "search_engine,action,bookmark",
|
||||
n_results: 3,
|
||||
},
|
||||
]),
|
||||
});
|
||||
|
@ -170,9 +170,9 @@ add_task(async function general() {
|
||||
assert: () =>
|
||||
assertEngagementTelemetry([
|
||||
{
|
||||
groups: "heuristic,general",
|
||||
results: "search_engine,bookmark",
|
||||
n_results: 2,
|
||||
groups: "heuristic,suggested_index,general",
|
||||
results: "search_engine,action,bookmark",
|
||||
n_results: 3,
|
||||
},
|
||||
]),
|
||||
});
|
||||
|
@ -101,6 +101,9 @@ add_task(async function selected_result_autofill_url() {
|
||||
|
||||
add_task(async function selected_result_bookmark() {
|
||||
await doTest(async () => {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.urlbar.secondaryActions.featureGate", false]],
|
||||
});
|
||||
await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
url: "https://example.com/bookmark",
|
||||
@ -938,11 +941,11 @@ add_task(async function selected_result_action() {
|
||||
|
||||
assertEngagementTelemetry([
|
||||
{
|
||||
selected_result: "action_settings",
|
||||
selected_position: 1,
|
||||
provider: "HeuristicFallback",
|
||||
results: "search_engine",
|
||||
actions: "settings",
|
||||
selected_result: "action",
|
||||
selected_position: 2,
|
||||
provider: "UrlbarProviderGlobalActions",
|
||||
results: "search_engine,action",
|
||||
actions: "none",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -10,28 +10,28 @@ ChromeUtils.defineESModuleGetters(this, {
|
||||
});
|
||||
|
||||
add_setup(async () => {
|
||||
UrlbarPrefs.set("quickactions.enabled", true);
|
||||
UrlbarPrefs.set("secondaryActions.featureGate", true);
|
||||
|
||||
ActionsProviderQuickActions.addAction("newaction", {
|
||||
commands: ["newaction"],
|
||||
});
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
UrlbarPrefs.clear("quickactions.enabled");
|
||||
UrlbarPrefs.clear("secondaryActions.featureGate");
|
||||
ActionsProviderQuickActions.removeAction("newaction");
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function nomatch() {
|
||||
let context = createContext("this doesnt match", {});
|
||||
let result = await ActionsProviderQuickActions.queryAction(context);
|
||||
Assert.ok(result === null, "there were no matches");
|
||||
let results = await ActionsProviderQuickActions.queryActions(context);
|
||||
Assert.ok(results === null, "there were no matches");
|
||||
});
|
||||
|
||||
add_task(async function quickactions_match() {
|
||||
let context = createContext("new", {});
|
||||
let result = await ActionsProviderQuickActions.queryAction(context);
|
||||
Assert.ok(result.key == "newaction", "Matched the new action");
|
||||
let results = await ActionsProviderQuickActions.queryActions(context);
|
||||
Assert.ok(results[0].key == "newaction", "Matched the new action");
|
||||
});
|
||||
|
||||
add_task(async function duplicate_matches() {
|
||||
@ -40,9 +40,9 @@ add_task(async function duplicate_matches() {
|
||||
});
|
||||
|
||||
let context = createContext("test", {});
|
||||
let result = await ActionsProviderQuickActions.queryAction(context);
|
||||
let results = await ActionsProviderQuickActions.queryActions(context);
|
||||
|
||||
Assert.ok(result.key == "testaction", "Matched the test action");
|
||||
Assert.ok(results[0].key == "testaction", "Matched the test action");
|
||||
|
||||
ActionsProviderQuickActions.removeAction("testaction");
|
||||
});
|
||||
@ -54,7 +54,7 @@ add_task(async function remove_action() {
|
||||
ActionsProviderQuickActions.removeAction("testaction");
|
||||
|
||||
let context = createContext("test", {});
|
||||
let result = await ActionsProviderQuickActions.queryAction(context);
|
||||
let result = await ActionsProviderQuickActions.queryActions(context);
|
||||
|
||||
Assert.ok(result === null, "there were no matches");
|
||||
});
|
||||
@ -66,11 +66,11 @@ add_task(async function minimum_search_string() {
|
||||
UrlbarPrefs.set("quickactions.minimumSearchString", minimumSearchString);
|
||||
for (let i = 1; i < 4; i++) {
|
||||
let context = createContext(searchString.substring(0, i), {});
|
||||
let result = await ActionsProviderQuickActions.queryAction(context);
|
||||
let result = await ActionsProviderQuickActions.queryActions(context);
|
||||
let isActive = ActionsProviderQuickActions.isActive(context);
|
||||
|
||||
if (i >= minimumSearchString) {
|
||||
Assert.ok(result.key == "newaction", "Matched the new action");
|
||||
Assert.ok(result[0].key == "newaction", "Matched the new action");
|
||||
Assert.equal(isActive, true, "Provider is active");
|
||||
} else {
|
||||
Assert.equal(isActive, false, "Provider is not active");
|
||||
|
@ -164,66 +164,14 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick actions
|
||||
* Actions
|
||||
*/
|
||||
|
||||
.urlbarView-dynamic-quickactions-buttons {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
gap: 0.9em 1.8em;
|
||||
max-width: 100%;
|
||||
|
||||
&[data-is-quickactions-searchmode] {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.urlbarView-quickaction-button {
|
||||
font-size: var(--urlbarView-small-font-size);
|
||||
font-weight: var(--font-weight-bold);
|
||||
box-shadow: 0 0 1px rgba(128, 128, 142, 0.9), 0 0 4px rgba(128, 128, 142, 0.5);
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
padding: .5em;
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
min-width: 16px;
|
||||
|
||||
&[disabled] {
|
||||
opacity: var(--toolbarbutton-disabled-opacity);
|
||||
}
|
||||
|
||||
&:hover:not([disabled]):not([selected]) {
|
||||
background-color: var(--urlbarView-hover-background);
|
||||
}
|
||||
|
||||
&[selected] {
|
||||
background-color: var(--urlbarView-highlight-background);
|
||||
color: var(--urlbarView-highlight-color);
|
||||
}
|
||||
|
||||
> .urlbarView-label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
> .urlbarView-favicon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-inline: 0 .5em;
|
||||
|
||||
> .urlbarView-favicon-img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.urlbarView-row[dynamicType=quickactions][label]::before {
|
||||
top: -1em;
|
||||
margin-inline-start: 6px;
|
||||
.urlbarView-row[dynamicType=actions] > .urlbarView-row-inner {
|
||||
/* Reduce the padding to 2px so the outline does not get
|
||||
cropped and the actions + outline are aligned with the
|
||||
rest of the results */
|
||||
padding-inline: 2px;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,9 +52,8 @@
|
||||
--urlbarView-labeled-row-label-top: calc(-1.27em - 2px);
|
||||
--urlbarView-labeled-tip-margin-top-extra: 8px;
|
||||
|
||||
--urlbarView-action-button-background-color: light-dark(white, var(--color-gray-90));
|
||||
--urlbarView-action-button-hover-color: light-dark(var(--color-gray-70), var(--color-gray-05));
|
||||
--urlbarView-action-button-selected-color: light-dark(var(--color-gray-90), var(--urlbarView-action-button-background-color));
|
||||
--urlbarView-action-button-background-color: color-mix(in srgb, var(--urlbarView-hover-background) 50%, transparent);
|
||||
--urlbarView-action-button-hover-background-color: var(--urlbarView-hover-background);
|
||||
|
||||
&:-moz-locale-dir(rtl) {
|
||||
--urlbarView-action-slide-in-distance: -200px;
|
||||
@ -962,14 +961,14 @@
|
||||
|
||||
.urlbarView-action-btn {
|
||||
font-size: smaller;
|
||||
color: var(--toolbar-field-focus-color);
|
||||
font-weight: var(--font-weight-bold);
|
||||
border-radius: var(--toolbarbutton-border-radius);
|
||||
border: 1px solid transparent;
|
||||
padding: .4em .6em;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background-color: var(--urlbarView-action-button-background-color);
|
||||
box-shadow: 0 0px 4px rgba(0, 0, 0, 0.23);
|
||||
margin-inline-end: var(--space-large);
|
||||
|
||||
> img {
|
||||
width: 16px;
|
||||
@ -979,14 +978,12 @@
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--urlbarView-result-button-hover-color);
|
||||
background-color: var(--urlbarView-action-button-hover-color);
|
||||
background-color: var(--urlbarView-action-button-hover-background-color);
|
||||
}
|
||||
|
||||
&[selected] {
|
||||
color: light-dark(var(--urlbarView-result-button-hover-color), var(--toolbar-field-focus-color));
|
||||
background-color: var(--urlbarView-action-button-selected-color);
|
||||
border-color: light-dark(transparent, white);
|
||||
&[selected],
|
||||
&:hover:active {
|
||||
outline: var(--focus-outline);
|
||||
}
|
||||
|
||||
&.urlbarView-userContext {
|
||||
|
Loading…
Reference in New Issue
Block a user