зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1810647 - Prepare for enable urlbar result menu in Nightly. r=mak,fluent-reviewers,flod
Differential Revision: https://phabricator.services.mozilla.com/D167004
This commit is contained in:
Родитель
dcf59d8716
Коммит
05e5fefb46
|
@ -46,7 +46,7 @@ function isEventForMenuItem(event) {
|
|||
return event.accessible.role == ROLE_MENUITEM;
|
||||
}
|
||||
|
||||
function isEventForTipButton(event) {
|
||||
function isEventForResultButton(event) {
|
||||
let parent = event.accessible.parent;
|
||||
return (
|
||||
event.accessible.role == ROLE_PUSHBUTTON &&
|
||||
|
@ -403,14 +403,14 @@ async function runTipTests() {
|
|||
|
||||
info("Ensuring the tip button is focused on down arrow");
|
||||
info("Also ensuring that the tip button is a part of a labelled group");
|
||||
focused = waitForEvent(EVENT_FOCUS, isEventForTipButton);
|
||||
focused = waitForEvent(EVENT_FOCUS, isEventForResultButton);
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
event = await focused;
|
||||
testStates(event.accessible, STATE_FOCUSED);
|
||||
|
||||
info("Ensuring the help button is focused on tab");
|
||||
info("Also ensuring that the help button is a part of a labelled group");
|
||||
focused = waitForEvent(EVENT_FOCUS, isEventForTipButton);
|
||||
focused = waitForEvent(EVENT_FOCUS, isEventForResultButton);
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
event = await focused;
|
||||
testStates(event.accessible, STATE_FOCUSED);
|
||||
|
@ -422,7 +422,7 @@ async function runTipTests() {
|
|||
testStates(event.accessible, STATE_FOCUSED);
|
||||
|
||||
info("Ensuring the help button is focused on shift+tab");
|
||||
focused = waitForEvent(EVENT_FOCUS, isEventForTipButton);
|
||||
focused = waitForEvent(EVENT_FOCUS, isEventForResultButton);
|
||||
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
|
||||
event = await focused;
|
||||
testStates(event.accessible, STATE_FOCUSED);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
ChromeUtils.defineESModuleGetters(this, {
|
||||
PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
|
||||
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
|
||||
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
|
||||
UrlbarProvidersManager: "resource:///modules/UrlbarProvidersManager.sys.mjs",
|
||||
UrlbarTestUtils: "resource://testing-common/UrlbarTestUtils.sys.mjs",
|
||||
});
|
||||
|
@ -91,8 +92,10 @@ async function updateTopSites(condition, searchShortcuts = false) {
|
|||
}
|
||||
|
||||
add_setup(async function() {
|
||||
UrlbarTestUtils.init(this);
|
||||
Services.prefs.setBoolPref("browser.urlbar.suggest.quickactions", false);
|
||||
registerCleanupFunction(async () => {
|
||||
UrlbarTestUtils.uninit();
|
||||
Services.prefs.clearUserPref("browser.urlbar.suggest.quickactions");
|
||||
});
|
||||
// Set the notification timeout to a really high value to avoid intermittent
|
||||
|
@ -188,16 +191,27 @@ add_task(async function tip_onResultPicked_helpButton_url_enter() {
|
|||
waitForFocus,
|
||||
value: "test",
|
||||
});
|
||||
let loadedPromise = BrowserTestUtils.browserLoaded(
|
||||
gBrowser.selectedBrowser
|
||||
);
|
||||
ext.onMessage("onResultPicked received", () => {
|
||||
Assert.ok(false, "onResultPicked should not be called");
|
||||
});
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
EventUtils.synthesizeKey("KEY_Enter");
|
||||
await loadedPromise;
|
||||
Assert.equal(gBrowser.currentURI.spec, "http://example.com/");
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
let tabOpenPromise = BrowserTestUtils.waitForNewTab(
|
||||
gBrowser,
|
||||
"http://example.com/"
|
||||
);
|
||||
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "h");
|
||||
info("Waiting for help URL to load in a new tab");
|
||||
await tabOpenPromise;
|
||||
gBrowser.removeCurrentTab();
|
||||
} else {
|
||||
let loadedPromise = BrowserTestUtils.browserLoaded(
|
||||
gBrowser.selectedBrowser
|
||||
);
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
EventUtils.synthesizeKey("KEY_Enter");
|
||||
await loadedPromise;
|
||||
Assert.equal(gBrowser.currentURI.spec, "http://example.com/");
|
||||
}
|
||||
});
|
||||
await ext.unload();
|
||||
});
|
||||
|
@ -211,17 +225,30 @@ add_task(async function tip_onResultPicked_helpButton_url_mouse() {
|
|||
waitForFocus,
|
||||
value: "test",
|
||||
});
|
||||
let helpButton = gURLBar.querySelector(".urlbarView-button-help");
|
||||
Assert.ok(helpButton);
|
||||
let loadedPromise = BrowserTestUtils.browserLoaded(
|
||||
gBrowser.selectedBrowser
|
||||
);
|
||||
ext.onMessage("onResultPicked received", () => {
|
||||
Assert.ok(false, "onResultPicked should not be called");
|
||||
});
|
||||
EventUtils.synthesizeMouseAtCenter(helpButton, {});
|
||||
await loadedPromise;
|
||||
Assert.equal(gBrowser.currentURI.spec, "http://example.com/");
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
let tabOpenPromise = BrowserTestUtils.waitForNewTab(
|
||||
gBrowser,
|
||||
"http://example.com/"
|
||||
);
|
||||
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "h", {
|
||||
openByMouse: true,
|
||||
});
|
||||
info("Waiting for help URL to load in a new tab");
|
||||
await tabOpenPromise;
|
||||
gBrowser.removeCurrentTab();
|
||||
} else {
|
||||
let loadedPromise = BrowserTestUtils.browserLoaded(
|
||||
gBrowser.selectedBrowser
|
||||
);
|
||||
let helpButton = gURLBar.querySelector(".urlbarView-button-help");
|
||||
Assert.ok(helpButton);
|
||||
EventUtils.synthesizeMouseAtCenter(helpButton, {});
|
||||
await loadedPromise;
|
||||
Assert.equal(gBrowser.currentURI.spec, "http://example.com/");
|
||||
}
|
||||
});
|
||||
await ext.unload();
|
||||
});
|
||||
|
|
|
@ -382,6 +382,11 @@ add_task(async function test_onProviderResultsRequested() {
|
|||
buttonText: "Test tip-local result button text",
|
||||
buttonUrl: "https://example.com/tip-button",
|
||||
helpUrl: "https://example.com/tip-help",
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-tip-get-help"
|
||||
: "urlbar-tip-help-icon",
|
||||
},
|
||||
type: "extension",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -362,7 +362,12 @@ export class UrlbarProviderExtension extends UrlbarProvider {
|
|||
|
||||
let type = UrlbarProviderExtension.RESULT_TYPES[extResult.type];
|
||||
if (type == UrlbarUtils.RESULT_TYPE.TIP) {
|
||||
extResult.payload.type = extResult.payload.type || "extension";
|
||||
extResult.payload.type ||= "extension";
|
||||
extResult.payload.helpL10n = {
|
||||
id: lazy.UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-tip-get-help"
|
||||
: "urlbar-tip-help-icon",
|
||||
};
|
||||
}
|
||||
|
||||
let result = new lazy.UrlbarResult(
|
||||
|
|
|
@ -15,6 +15,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
|||
NLP: "resource://gre/modules/NLP.sys.mjs",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
|
||||
ResetProfile: "resource://gre/modules/ResetProfile.sys.mjs",
|
||||
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
|
||||
UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs",
|
||||
UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.sys.mjs",
|
||||
});
|
||||
|
@ -660,7 +661,11 @@ class ProviderInterventions extends UrlbarProvider {
|
|||
...getPayloadForTip(this.currentTip),
|
||||
type: this.currentTip,
|
||||
icon: UrlbarUtils.ICON.TIP,
|
||||
helpL10n: { id: "urlbar-tip-help-icon" },
|
||||
helpL10n: {
|
||||
id: lazy.UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-tip-get-help"
|
||||
: "urlbar-tip-help-icon",
|
||||
},
|
||||
}
|
||||
);
|
||||
result.suggestedIndex = 1;
|
||||
|
|
|
@ -1105,7 +1105,6 @@ export class UrlbarView {
|
|||
#createRow() {
|
||||
let item = this.#createElement("div");
|
||||
item.className = "urlbarView-row";
|
||||
item.setAttribute("role", "option");
|
||||
item._elements = new Map();
|
||||
item._buttons = new Map();
|
||||
return item;
|
||||
|
@ -1372,6 +1371,7 @@ export class UrlbarView {
|
|||
while (item.lastChild) {
|
||||
item.lastChild.remove();
|
||||
}
|
||||
item.setAttribute("role", "option");
|
||||
item._elements.clear();
|
||||
item._buttons.clear();
|
||||
item._content = this.#createElement("span");
|
||||
|
@ -2285,7 +2285,8 @@ export class UrlbarView {
|
|||
if (result.type != lazy.UrlbarUtils.RESULT_TYPE.TIP) {
|
||||
return false;
|
||||
}
|
||||
let tipButton = this.#rows.firstElementChild._buttons.get("0");
|
||||
let buttons = this.#rows.firstElementChild._buttons;
|
||||
let tipButton = buttons.get("tip") || buttons.get("0");
|
||||
if (!tipButton) {
|
||||
throw new Error("Expected a tip button");
|
||||
}
|
||||
|
|
|
@ -200,12 +200,87 @@ export var UrlbarTestUtils = {
|
|||
return win.gURLBar.view.oneOffSearchButtons;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a specific button of a result.
|
||||
*
|
||||
* @param {object} win The window containing the urlbar
|
||||
* @param {string} buttonName The name of the button, e.g. "menu", "0", etc.
|
||||
* @param {number} resultIndex The index of the result
|
||||
* @returns {HtmlElement} The button
|
||||
*/
|
||||
getButtonForResultIndex(win, buttonName, resultIndex) {
|
||||
return this.getRowAt(win, resultIndex).querySelector(
|
||||
`.urlbarView-button-${buttonName}`
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens the result menu of a specific result and presses an access key to
|
||||
* activate a menu item.
|
||||
*
|
||||
* @param {object} win The window containing the urlbar
|
||||
* @param {string} accesskey The access key to press once the menu is open
|
||||
* @param {object} [options] The options object.
|
||||
* @param {number} [options.resultIndex] The index of the result. Defaults
|
||||
* to the current selected index.
|
||||
* @param {boolean} [options.openByMouse] Whether to open the menu by mouse
|
||||
* or keyboard.
|
||||
*/
|
||||
async openResultMenuAndPressAccesskey(
|
||||
win,
|
||||
accesskey,
|
||||
{
|
||||
resultIndex = win.gURLBar.view.selectedRowIndex,
|
||||
openByMouse = false,
|
||||
} = {}
|
||||
) {
|
||||
let menuButton = this.getButtonForResultIndex(win, "menu", resultIndex);
|
||||
this.Assert?.ok(
|
||||
menuButton,
|
||||
`found the menu button at result index ${resultIndex}`
|
||||
);
|
||||
let promiseMenuOpen = lazy.BrowserTestUtils.waitForEvent(
|
||||
win.gURLBar.view.resultMenu,
|
||||
"popupshown"
|
||||
);
|
||||
this._testScope?.info(`selecting the result at index ${resultIndex}`);
|
||||
while (win.gURLBar.view.selectedRowIndex != resultIndex) {
|
||||
this.EventUtils.synthesizeKey("KEY_ArrowDown", {}, win);
|
||||
}
|
||||
if (openByMouse) {
|
||||
this.EventUtils.synthesizeMouseAtCenter(menuButton, {}, win);
|
||||
} else {
|
||||
this.EventUtils.synthesizeKey("KEY_Tab", {}, win);
|
||||
this.Assert?.equal(
|
||||
this.getSelectedElement(win),
|
||||
menuButton,
|
||||
`selected the menu button at result index ${resultIndex}`
|
||||
);
|
||||
this.EventUtils.synthesizeKey("KEY_Enter", {}, win);
|
||||
}
|
||||
this._testScope?.info("waiting for the menu to open");
|
||||
await promiseMenuOpen;
|
||||
await lazy.BrowserTestUtils.waitForCondition(
|
||||
() =>
|
||||
win.gURLBar.view.resultMenu.querySelector(
|
||||
`menuitem[accesskey=${accesskey}]`
|
||||
),
|
||||
"Waiting for strings to load"
|
||||
);
|
||||
|
||||
this._testScope?.info(
|
||||
`pressing access key (${accesskey}) to activate menu item`
|
||||
);
|
||||
let promiseCommand = lazy.BrowserTestUtils.waitForEvent(
|
||||
win.gURLBar.view.resultMenu,
|
||||
"command"
|
||||
);
|
||||
this.EventUtils.synthesizeKey(accesskey, {}, win);
|
||||
this._testScope?.info("waiting for command event");
|
||||
await promiseCommand;
|
||||
this._testScope?.info("got the command event");
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the oneOffSearchButtons are visible.
|
||||
*
|
||||
|
|
|
@ -247,7 +247,11 @@ add_task(async function pickHelpButton() {
|
|||
},
|
||||
],
|
||||
helpUrl,
|
||||
helpL10n: { id: "urlbar-tip-help-icon" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-tip-get-help"
|
||||
: "urlbar-tip-help-icon",
|
||||
},
|
||||
}
|
||||
),
|
||||
];
|
||||
|
@ -268,17 +272,38 @@ add_task(async function pickHelpButton() {
|
|||
UrlbarProviderInterventions.TIP_TYPE.CLEAR
|
||||
);
|
||||
|
||||
let helpButton = element._buttons.get("help");
|
||||
Assert.ok(helpButton, "Help button exists");
|
||||
Assert.ok(
|
||||
BrowserTestUtils.is_visible(helpButton),
|
||||
"Help button is visible"
|
||||
);
|
||||
EventUtils.synthesizeMouseAtCenter(helpButton, {});
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
let tabOpenPromise = BrowserTestUtils.waitForNewTab(
|
||||
gBrowser,
|
||||
"http://example.com/"
|
||||
);
|
||||
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "h", {
|
||||
openByMouse: true,
|
||||
resultIndex: 1,
|
||||
});
|
||||
info("Waiting for help URL to load in a new tab");
|
||||
await tabOpenPromise;
|
||||
gBrowser.removeCurrentTab();
|
||||
} else {
|
||||
let helpButton = element._buttons.get("help");
|
||||
Assert.ok(helpButton, "Help button exists");
|
||||
Assert.ok(
|
||||
BrowserTestUtils.is_visible(helpButton),
|
||||
"Help button is visible"
|
||||
);
|
||||
EventUtils.synthesizeMouseAtCenter(helpButton, {});
|
||||
|
||||
BrowserTestUtils.loadURIString(gBrowser.selectedBrowser, helpUrl);
|
||||
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
BrowserTestUtils.loadURIString(gBrowser.selectedBrowser, helpUrl);
|
||||
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
}
|
||||
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
todo(
|
||||
false,
|
||||
"help telemetry for the result menu to be implemented in bug 1790020"
|
||||
);
|
||||
return;
|
||||
}
|
||||
const scalars = TelemetryTestUtils.getProcessScalars("parent", true, true);
|
||||
TelemetryTestUtils.assertKeyedScalar(
|
||||
scalars,
|
||||
|
|
|
@ -105,6 +105,14 @@ add_task(async function mouse_insideTipButNotOnButtons() {
|
|||
* to pick the main button instead.
|
||||
*/
|
||||
async function doTest({ click, buttonUrl = undefined, helpUrl = undefined }) {
|
||||
if (UrlbarPrefs.get("resultMenu") && helpUrl) {
|
||||
todo(
|
||||
false,
|
||||
"help telemetry for the result menu to be implemented in bug 1790020"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Open a new tab for the test if we expect to load a URL.
|
||||
let tab;
|
||||
if (buttonUrl || helpUrl) {
|
||||
|
|
|
@ -45,7 +45,7 @@ add_task(async function tipIsSecondResult() {
|
|||
"The first element should be selected."
|
||||
);
|
||||
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
Assert.ok(
|
||||
UrlbarTestUtils.getSelectedElement(window).classList.contains(
|
||||
"urlbarView-button-0"
|
||||
|
@ -54,26 +54,32 @@ add_task(async function tipIsSecondResult() {
|
|||
);
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getSelectedElementIndex(window),
|
||||
1,
|
||||
"The first element should be selected."
|
||||
UrlbarPrefs.get("resultMenu") ? 2 : 1,
|
||||
"Selected element index"
|
||||
);
|
||||
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
Assert.ok(
|
||||
UrlbarTestUtils.getSelectedElement(window).classList.contains(
|
||||
"urlbarView-button-help"
|
||||
UrlbarPrefs.get("resultMenu")
|
||||
? "urlbarView-button-menu"
|
||||
: "urlbarView-button-help"
|
||||
),
|
||||
"The selected element should be the tip help button."
|
||||
UrlbarPrefs.get("resultMenu")
|
||||
? "The selected element should be the tip menu button."
|
||||
: "The selected element should be the tip help button."
|
||||
);
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getSelectedRowIndex(window),
|
||||
1,
|
||||
"getSelectedRowIndex should return 1 even though the help button is selected."
|
||||
UrlbarPrefs.get("resultMenu")
|
||||
? "getSelectedRowIndex should return 1 even though the menu button is selected."
|
||||
: "getSelectedRowIndex should return 1 even though the help button is selected."
|
||||
);
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getSelectedElementIndex(window),
|
||||
2,
|
||||
"The third element should be selected."
|
||||
UrlbarPrefs.get("resultMenu") ? 3 : 2,
|
||||
"Selected element index"
|
||||
);
|
||||
|
||||
// If this test is running alone, the one-offs will rebuild themselves when
|
||||
|
@ -101,9 +107,13 @@ add_task(async function tipIsSecondResult() {
|
|||
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
|
||||
Assert.ok(
|
||||
UrlbarTestUtils.getSelectedElement(window).classList.contains(
|
||||
"urlbarView-button-help"
|
||||
UrlbarPrefs.get("resultMenu")
|
||||
? "urlbarView-button-menu"
|
||||
: "urlbarView-button-help"
|
||||
),
|
||||
"The selected element should be the tip help button."
|
||||
UrlbarPrefs.get("resultMenu")
|
||||
? "The selected element should be the tip menu button."
|
||||
: "The selected element should be the tip help button."
|
||||
);
|
||||
|
||||
gURLBar.view.close();
|
||||
|
@ -149,9 +159,13 @@ add_task(async function tipIsOnlyResult() {
|
|||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
Assert.ok(
|
||||
UrlbarTestUtils.getSelectedElement(window).classList.contains(
|
||||
"urlbarView-button-help"
|
||||
UrlbarPrefs.get("resultMenu")
|
||||
? "urlbarView-button-menu"
|
||||
: "urlbarView-button-help"
|
||||
),
|
||||
"The selected element should be the tip help button."
|
||||
UrlbarPrefs.get("resultMenu")
|
||||
? "The selected element should be the tip menu button."
|
||||
: "The selected element should be the tip help button."
|
||||
);
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getSelectedElementIndex(window),
|
||||
|
@ -169,9 +183,13 @@ add_task(async function tipIsOnlyResult() {
|
|||
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
|
||||
Assert.ok(
|
||||
UrlbarTestUtils.getSelectedElement(window).classList.contains(
|
||||
"urlbarView-button-help"
|
||||
UrlbarPrefs.get("resultMenu")
|
||||
? "urlbarView-button-menu"
|
||||
: "urlbarView-button-help"
|
||||
),
|
||||
"The selected element should be the tip help button."
|
||||
UrlbarPrefs.get("resultMenu")
|
||||
? "The selected element should be the tip menu button."
|
||||
: "The selected element should be the tip help button."
|
||||
);
|
||||
|
||||
gURLBar.view.close();
|
||||
|
@ -224,8 +242,8 @@ add_task(async function tipHasNoHelpButton() {
|
|||
);
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getSelectedElementIndex(window),
|
||||
1,
|
||||
"The first element should be selected."
|
||||
UrlbarPrefs.get("resultMenu") ? 2 : 1,
|
||||
"Selected element index"
|
||||
);
|
||||
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
|
|
|
@ -333,7 +333,11 @@ async function doUpdateTest({
|
|||
Assert.ok(button.test(actualButton), "Button regexp");
|
||||
}
|
||||
|
||||
Assert.ok(element._buttons.has("help"), "Tip has a help button");
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
Assert.ok(element._buttons.has("menu"), "Tip has a menu button");
|
||||
} else {
|
||||
Assert.ok(element._buttons.has("help"), "Tip has a help button");
|
||||
}
|
||||
|
||||
// Pick the tip and wait for the action.
|
||||
let values = await Promise.all([awaitCallback(), pickTip()]);
|
||||
|
@ -488,12 +492,21 @@ function checkIntervention({
|
|||
Assert.ok(button.test(actualButton), "Button regexp");
|
||||
}
|
||||
|
||||
let helpButton = element._buttons.get("help");
|
||||
Assert.ok(helpButton, "Help button exists");
|
||||
Assert.ok(
|
||||
BrowserTestUtils.is_visible(helpButton),
|
||||
"Help button is visible"
|
||||
);
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
let menuButton = element._buttons.get("menu");
|
||||
Assert.ok(menuButton, "Menu button exists");
|
||||
Assert.ok(
|
||||
BrowserTestUtils.is_visible(menuButton),
|
||||
"Menu button is visible"
|
||||
);
|
||||
} else {
|
||||
let helpButton = element._buttons.get("help");
|
||||
Assert.ok(helpButton, "Help button exists");
|
||||
Assert.ok(
|
||||
BrowserTestUtils.is_visible(helpButton),
|
||||
"Help button is visible"
|
||||
);
|
||||
}
|
||||
|
||||
let values = await Promise.all([awaitCallback(), pickTip()]);
|
||||
Assert.ok(true, "Refresh dialog opened");
|
||||
|
|
|
@ -241,7 +241,13 @@ add_suggestedIndex_task({
|
|||
type: UrlbarUtils.RESULT_TYPE.URL,
|
||||
suggestedIndex: 1,
|
||||
},
|
||||
{ count: 8, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{ count: 1, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{
|
||||
count: 7,
|
||||
type: UrlbarPrefs.get("resultMenu")
|
||||
? UrlbarUtils.RESULT_TYPE.URL
|
||||
: UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
@ -516,7 +522,13 @@ add_suggestedIndex_task({
|
|||
},
|
||||
duringUpdate: [
|
||||
{ count: 1 },
|
||||
{ count: 8, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{ count: 1, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{
|
||||
count: 7,
|
||||
type: UrlbarPrefs.get("resultMenu")
|
||||
? UrlbarUtils.RESULT_TYPE.URL
|
||||
: UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
},
|
||||
{
|
||||
count: 1,
|
||||
type: UrlbarUtils.RESULT_TYPE.URL,
|
||||
|
@ -708,7 +720,13 @@ add_suggestedIndex_task({
|
|||
},
|
||||
duringUpdate: [
|
||||
{ count: 1 },
|
||||
{ count: 8, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{ count: 1, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{
|
||||
count: 7,
|
||||
type: UrlbarPrefs.get("resultMenu")
|
||||
? UrlbarUtils.RESULT_TYPE.URL
|
||||
: UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
},
|
||||
{
|
||||
count: 1,
|
||||
type: UrlbarUtils.RESULT_TYPE.URL,
|
||||
|
@ -909,7 +927,13 @@ add_suggestedIndex_task({
|
|||
type: UrlbarUtils.RESULT_TYPE.URL,
|
||||
suggestedIndex: -9,
|
||||
},
|
||||
{ count: 8, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{ count: 1, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{
|
||||
count: 7,
|
||||
type: UrlbarPrefs.get("resultMenu")
|
||||
? UrlbarUtils.RESULT_TYPE.URL
|
||||
: UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
@ -207,7 +207,13 @@ add_suggestedIndex_task({
|
|||
type: UrlbarUtils.RESULT_TYPE.URL,
|
||||
suggestedIndex: 1,
|
||||
},
|
||||
{ count: 3, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{ count: 1, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{
|
||||
count: 2,
|
||||
type: UrlbarPrefs.get("resultMenu")
|
||||
? UrlbarUtils.RESULT_TYPE.URL
|
||||
: UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
@ -524,7 +530,13 @@ add_suggestedIndex_task({
|
|||
},
|
||||
duringUpdate: [
|
||||
{ count: 1 },
|
||||
{ count: 3, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{ count: 1, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{
|
||||
count: 2,
|
||||
type: UrlbarPrefs.get("resultMenu")
|
||||
? UrlbarUtils.RESULT_TYPE.URL
|
||||
: UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
},
|
||||
{
|
||||
count: 1,
|
||||
type: UrlbarUtils.RESULT_TYPE.URL,
|
||||
|
@ -798,7 +810,13 @@ add_suggestedIndex_task({
|
|||
},
|
||||
duringUpdate: [
|
||||
{ count: 1 },
|
||||
{ count: 3, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{ count: 1, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{
|
||||
count: 2,
|
||||
type: UrlbarPrefs.get("resultMenu")
|
||||
? UrlbarUtils.RESULT_TYPE.URL
|
||||
: UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
},
|
||||
{
|
||||
count: 1,
|
||||
type: UrlbarUtils.RESULT_TYPE.URL,
|
||||
|
@ -1037,13 +1055,24 @@ add_suggestedIndex_task({
|
|||
},
|
||||
duringUpdate: [
|
||||
{ count: 1 },
|
||||
{ count: 2, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{ count: 1, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{
|
||||
count: 1,
|
||||
type: UrlbarPrefs.get("resultMenu")
|
||||
? UrlbarUtils.RESULT_TYPE.URL
|
||||
: UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
},
|
||||
{
|
||||
count: 1,
|
||||
type: UrlbarUtils.RESULT_TYPE.URL,
|
||||
suggestedIndex: -2,
|
||||
},
|
||||
{ count: 1, type: UrlbarUtils.RESULT_TYPE.SEARCH },
|
||||
{
|
||||
count: 1,
|
||||
type: UrlbarPrefs.get("resultMenu")
|
||||
? UrlbarUtils.RESULT_TYPE.URL
|
||||
: UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
@ -20,13 +20,6 @@ function assertSelected(index) {
|
|||
index,
|
||||
"Should have selected the correct item"
|
||||
);
|
||||
// Also check the "selected" attribute, to ensure it is not a "fake" selection
|
||||
// due to binding misbehaviors.
|
||||
let element = UrlbarTestUtils.getSelectedRow(window);
|
||||
Assert.ok(
|
||||
element.hasAttribute("selected"),
|
||||
"Should have the selected attribute on the row element"
|
||||
);
|
||||
|
||||
// This is true because although both the listbox and the one-offs can have
|
||||
// selections, the test doesn't check that.
|
||||
|
|
|
@ -32,7 +32,7 @@ add_task(async function nonsponsoredHelpButton() {
|
|||
window,
|
||||
value: "test",
|
||||
});
|
||||
await checkBestMatchRow({ result, hasHelpButton: true });
|
||||
await checkBestMatchRow({ result, hasHelpUrl: true });
|
||||
await UrlbarTestUtils.promisePopupClose(window);
|
||||
});
|
||||
});
|
||||
|
@ -61,7 +61,7 @@ add_task(async function sponsoredHelpButton() {
|
|||
window,
|
||||
value: "test",
|
||||
});
|
||||
await checkBestMatchRow({ result, isSponsored: true, hasHelpButton: true });
|
||||
await checkBestMatchRow({ result, isSponsored: true, hasHelpUrl: true });
|
||||
await UrlbarTestUtils.promisePopupClose(window);
|
||||
});
|
||||
});
|
||||
|
@ -75,7 +75,12 @@ add_task(async function keySelection() {
|
|||
|
||||
await withProvider(result, async () => {
|
||||
// Ordered list of class names of the elements that should be selected.
|
||||
let expectedClassNames = ["urlbarView-row-inner", "urlbarView-button-help"];
|
||||
let expectedClassNames = [
|
||||
"urlbarView-row-inner",
|
||||
UrlbarPrefs.get("resultMenu")
|
||||
? "urlbarView-button-menu"
|
||||
: "urlbarView-button-help",
|
||||
];
|
||||
|
||||
await UrlbarTestUtils.promiseAutocompleteResultPopup({
|
||||
window,
|
||||
|
@ -84,7 +89,7 @@ add_task(async function keySelection() {
|
|||
await checkBestMatchRow({
|
||||
result,
|
||||
isSponsored: true,
|
||||
hasHelpButton: true,
|
||||
hasHelpUrl: true,
|
||||
});
|
||||
|
||||
// Test with the tab key in order vs. reverse order.
|
||||
|
@ -126,7 +131,7 @@ add_task(async function keySelection() {
|
|||
async function checkBestMatchRow({
|
||||
result,
|
||||
isSponsored = false,
|
||||
hasHelpButton = false,
|
||||
hasHelpUrl = false,
|
||||
}) {
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getResultCount(window),
|
||||
|
@ -177,16 +182,21 @@ async function checkBestMatchRow({
|
|||
);
|
||||
}
|
||||
|
||||
let helpButton = row._buttons.get("help");
|
||||
let button = row._buttons.get(
|
||||
UrlbarPrefs.get("resultMenu") ? "menu" : "help"
|
||||
);
|
||||
Assert.equal(
|
||||
!!result.payload.helpUrl,
|
||||
hasHelpButton,
|
||||
"Sanity check: Row's expected hasHelpButton matches result"
|
||||
hasHelpUrl,
|
||||
"Sanity check: Row's expected hasHelpUrl matches result"
|
||||
);
|
||||
if (hasHelpButton) {
|
||||
Assert.ok(helpButton, "Row with helpUrl has a helpButton");
|
||||
if (hasHelpUrl) {
|
||||
Assert.ok(button, "Row with helpUrl has a help or menu button");
|
||||
} else {
|
||||
Assert.ok(!helpButton, "Row without helpUrl does not have a helpButton");
|
||||
Assert.ok(
|
||||
!button,
|
||||
"Row without helpUrl does not have a help or menu button"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,10 @@ add_setup(async function() {
|
|||
// Sets `helpL10n` on the result payload and makes sure the help button ends
|
||||
// up with a corresponding l10n attribute.
|
||||
add_task(async function title_helpL10n() {
|
||||
let helpL10n = { id: "urlbar-tip-help-icon" };
|
||||
let provider = registerTestProvider(1, { helpL10n });
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
return;
|
||||
}
|
||||
let provider = registerTestProvider(1);
|
||||
await UrlbarTestUtils.promiseAutocompleteResultPopup({
|
||||
value: "example",
|
||||
window,
|
||||
|
@ -40,7 +42,7 @@ add_task(async function title_helpL10n() {
|
|||
let l10nAttrs = document.l10n.getAttributes(helpButton);
|
||||
Assert.deepEqual(
|
||||
l10nAttrs,
|
||||
{ id: helpL10n.id, args: null },
|
||||
{ id: "urlbar-tip-help-icon", args: null },
|
||||
"The l10n ID attribute was correctly set"
|
||||
);
|
||||
|
||||
|
@ -70,28 +72,30 @@ add_task(async function keyboardSelection_secondResult() {
|
|||
);
|
||||
await assertIsTestResult(1);
|
||||
|
||||
// TAB to the main part of the result.
|
||||
let resultMenuOffset = UrlbarPrefs.get("resultMenu") ? 1 : 0;
|
||||
|
||||
info("Arrow down to the main part of the result.");
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
assertMainPartSelected(1 + resultMenuOffset);
|
||||
|
||||
info("TAB to the button.");
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
assertMainPartSelected(1);
|
||||
assertButtonSelected(2 + resultMenuOffset);
|
||||
|
||||
// TAB to the help button.
|
||||
info("TAB to the next (third) result.");
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
assertHelpButtonSelected(2);
|
||||
assertOtherResultSelected(3 + resultMenuOffset, "next result");
|
||||
|
||||
// TAB to the next (third) result.
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
assertOtherResultSelected(3, "next result");
|
||||
|
||||
// SHIFT+TAB to the help button.
|
||||
info("SHIFT+TAB to the help button.");
|
||||
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
|
||||
assertHelpButtonSelected(2);
|
||||
assertButtonSelected(2 + resultMenuOffset);
|
||||
|
||||
// SHIFT+TAB to the main part of the result.
|
||||
info("SHIFT+TAB to the main part of the result.");
|
||||
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
|
||||
assertMainPartSelected(1);
|
||||
assertMainPartSelected(1 + resultMenuOffset);
|
||||
|
||||
// SHIFT+TAB to the previous (first) result.
|
||||
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
|
||||
info("Arrow up to the previous (first) result.");
|
||||
EventUtils.synthesizeKey("KEY_ArrowUp");
|
||||
assertOtherResultSelected(0, "previous result");
|
||||
|
||||
await UrlbarTestUtils.promisePopupClose(window);
|
||||
|
@ -120,13 +124,17 @@ add_task(async function keyboardSelection_lastResult() {
|
|||
);
|
||||
await assertIsTestResult(MAX_RESULTS - 1);
|
||||
|
||||
// TAB to the main part of the result.
|
||||
EventUtils.synthesizeKey("KEY_Tab", { repeat: MAX_RESULTS - 1 });
|
||||
assertMainPartSelected(MAX_RESULTS - 1);
|
||||
let numSelectable = UrlbarPrefs.get("resultMenu")
|
||||
? MAX_RESULTS * 2 - 1
|
||||
: MAX_RESULTS;
|
||||
|
||||
// Arrow down to the main part of the result.
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown", { repeat: MAX_RESULTS - 1 });
|
||||
assertMainPartSelected(numSelectable - 1);
|
||||
|
||||
// TAB to the help button.
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
assertHelpButtonSelected(MAX_RESULTS);
|
||||
assertButtonSelected(numSelectable);
|
||||
|
||||
// Arrow down to the first one-off. If this test is running alone, the
|
||||
// one-offs will rebuild themselves when the view is opened above, and they
|
||||
|
@ -153,15 +161,18 @@ add_task(async function keyboardSelection_lastResult() {
|
|||
|
||||
// SHIFT+TAB to the help button.
|
||||
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
|
||||
assertHelpButtonSelected(MAX_RESULTS);
|
||||
assertButtonSelected(numSelectable);
|
||||
|
||||
// SHIFT+TAB to the main part of the result.
|
||||
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
|
||||
assertMainPartSelected(MAX_RESULTS - 1);
|
||||
assertMainPartSelected(numSelectable - 1);
|
||||
|
||||
// SHIFT+TAB to the previous result.
|
||||
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
|
||||
assertOtherResultSelected(MAX_RESULTS - 2, "previous result");
|
||||
// Arrow up to the previous result.
|
||||
EventUtils.synthesizeKey("KEY_ArrowUp");
|
||||
assertOtherResultSelected(
|
||||
numSelectable - (UrlbarPrefs.get("resultMenu") ? 3 : 2),
|
||||
"previous result"
|
||||
);
|
||||
|
||||
await UrlbarTestUtils.promisePopupClose(window);
|
||||
UrlbarProvidersManager.unregisterProvider(provider);
|
||||
|
@ -170,26 +181,26 @@ add_task(async function keyboardSelection_lastResult() {
|
|||
// Picks the main part of the test result -- the non-help-button part -- with
|
||||
// the keyboard.
|
||||
add_task(async function pick_mainPart_keyboard() {
|
||||
await doPickTest({ pickHelpButton: false, useKeyboard: true });
|
||||
await doPickTest({ pickButton: false, useKeyboard: true });
|
||||
});
|
||||
|
||||
// Picks the help button with the keyboard.
|
||||
add_task(async function pick_helpButton_keyboard() {
|
||||
await doPickTest({ pickHelpButton: true, useKeyboard: true });
|
||||
await doPickTest({ pickButton: true, useKeyboard: true });
|
||||
});
|
||||
|
||||
// Picks the main part of the test result -- the non-help-button part -- with
|
||||
// the mouse.
|
||||
add_task(async function pick_mainPart_mouse() {
|
||||
await doPickTest({ pickHelpButton: false, useKeyboard: false });
|
||||
await doPickTest({ pickButton: false, useKeyboard: false });
|
||||
});
|
||||
|
||||
// Picks the help button with the mouse.
|
||||
add_task(async function pick_helpButton_mouse() {
|
||||
await doPickTest({ pickHelpButton: true, useKeyboard: false });
|
||||
await doPickTest({ pickButton: true, useKeyboard: false });
|
||||
});
|
||||
|
||||
async function doPickTest({ pickHelpButton, useKeyboard }) {
|
||||
async function doPickTest({ pickButton, useKeyboard }) {
|
||||
await BrowserTestUtils.withNewTab("about:blank", async () => {
|
||||
let index = 1;
|
||||
let provider = registerTestProvider(index);
|
||||
|
@ -204,51 +215,57 @@ async function doPickTest({ pickHelpButton, useKeyboard }) {
|
|||
0,
|
||||
"The heuristic result should be selected"
|
||||
);
|
||||
await assertIsTestResult(1);
|
||||
await assertIsTestResult(index);
|
||||
|
||||
let clickTarget;
|
||||
if (useKeyboard) {
|
||||
// TAB to the result.
|
||||
if (pickHelpButton) {
|
||||
EventUtils.synthesizeKey("KEY_Tab", { repeat: index + 1 });
|
||||
assertHelpButtonSelected(index + 1);
|
||||
} else {
|
||||
EventUtils.synthesizeKey("KEY_Tab", { repeat: index });
|
||||
assertMainPartSelected(index);
|
||||
}
|
||||
} else {
|
||||
// Get the click target.
|
||||
let result = await UrlbarTestUtils.getDetailsOfResultAt(window, index);
|
||||
clickTarget = pickHelpButton
|
||||
? result.element.row._buttons.get("help")
|
||||
: result.element.row._content;
|
||||
Assert.ok(
|
||||
clickTarget,
|
||||
"Click target found, pickHelpButton=" + pickHelpButton
|
||||
);
|
||||
// Arrow down to the result.
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown", { repeat: index });
|
||||
assertMainPartSelected(UrlbarPrefs.get("resultMenu") ? index * 2 : index);
|
||||
}
|
||||
|
||||
// Pick the result. The appropriate URL should load.
|
||||
let loadPromise = pickHelpButton
|
||||
let loadPromise = pickButton
|
||||
? BrowserTestUtils.waitForNewTab(gBrowser)
|
||||
: BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
await Promise.all([
|
||||
loadPromise,
|
||||
UrlbarTestUtils.promisePopupClose(window, () => {
|
||||
if (useKeyboard) {
|
||||
UrlbarTestUtils.promisePopupClose(window, async () => {
|
||||
if (pickButton && UrlbarPrefs.get("resultMenu")) {
|
||||
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "h", {
|
||||
openByMouse: !useKeyboard,
|
||||
resultIndex: index,
|
||||
});
|
||||
} else if (useKeyboard) {
|
||||
if (pickButton) {
|
||||
// TAB to the button.
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
assertButtonSelected(index + 1);
|
||||
}
|
||||
EventUtils.synthesizeKey("KEY_Enter");
|
||||
} else {
|
||||
// Get the click target.
|
||||
let result = await UrlbarTestUtils.getDetailsOfResultAt(
|
||||
window,
|
||||
index
|
||||
);
|
||||
let clickTarget = pickButton
|
||||
? result.element.row._buttons.get("help")
|
||||
: result.element.row._content;
|
||||
Assert.ok(
|
||||
clickTarget,
|
||||
"Click target found, pickButton=" + pickButton
|
||||
);
|
||||
EventUtils.synthesizeMouseAtCenter(clickTarget, {});
|
||||
}
|
||||
}),
|
||||
]);
|
||||
Assert.equal(
|
||||
gBrowser.selectedBrowser.currentURI.spec,
|
||||
pickHelpButton ? RESULT_HELP_URL : RESULT_URL,
|
||||
pickButton ? RESULT_HELP_URL : RESULT_URL,
|
||||
"Expected URL should have loaded"
|
||||
);
|
||||
|
||||
if (pickHelpButton) {
|
||||
if (pickButton) {
|
||||
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
}
|
||||
UrlbarProvidersManager.unregisterProvider(provider);
|
||||
|
@ -263,24 +280,24 @@ async function doPickTest({ pickHelpButton, useKeyboard }) {
|
|||
*
|
||||
* @param {number} suggestedIndex
|
||||
* The result's suggestedIndex.
|
||||
* @param {object} [extraPayloadProperties]
|
||||
* Properties other than `url` and `helpUrl` to set on the payload.
|
||||
* @returns {UrlbarProvider}
|
||||
* The new provider.
|
||||
*/
|
||||
function registerTestProvider(suggestedIndex, extraPayloadProperties = {}) {
|
||||
function registerTestProvider(suggestedIndex) {
|
||||
let results = [
|
||||
Object.assign(
|
||||
new UrlbarResult(
|
||||
UrlbarUtils.RESULT_TYPE.URL,
|
||||
UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
|
||||
Object.assign(
|
||||
{
|
||||
url: RESULT_URL,
|
||||
helpUrl: RESULT_HELP_URL,
|
||||
{
|
||||
url: RESULT_URL,
|
||||
helpUrl: RESULT_HELP_URL,
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-tip-get-help"
|
||||
: "urlbar-tip-help-icon",
|
||||
},
|
||||
extraPayloadProperties
|
||||
)
|
||||
}
|
||||
),
|
||||
{ suggestedIndex }
|
||||
),
|
||||
|
@ -311,9 +328,13 @@ async function assertIsTestResult(index) {
|
|||
);
|
||||
|
||||
let { row } = result.element;
|
||||
let helpButton = row._buttons.get("help");
|
||||
Assert.ok(helpButton, "The result should have a help button");
|
||||
Assert.ok(helpButton.id, "Help button has an ID");
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
Assert.ok(row._buttons.get("menu"), "The result should have a menu button");
|
||||
} else {
|
||||
let helpButton = row._buttons.get("help");
|
||||
Assert.ok(helpButton, "The result should have a help button");
|
||||
Assert.ok(helpButton.id, "Help button has an ID");
|
||||
}
|
||||
Assert.ok(row._content.id, "Row-inner has an ID");
|
||||
Assert.equal(
|
||||
row.getAttribute("role"),
|
||||
|
@ -347,7 +368,9 @@ function assertSelection(expectedSelectedElementIndex, expectedClassName, msg) {
|
|||
UrlbarTestUtils.getSelectedElement(window).classList.contains(
|
||||
expectedClassName
|
||||
),
|
||||
"Expected selected element: " + msg
|
||||
`Expected selected element: ${msg} (${
|
||||
UrlbarTestUtils.getSelectedElement(window).classList
|
||||
} == ${expectedClassName})`
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -367,17 +390,25 @@ function assertMainPartSelected(expectedSelectedElementIndex) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Asserts that the help button part of our test resut is selected.
|
||||
* Asserts that the help button part of our test result is selected.
|
||||
*
|
||||
* @param {number} expectedSelectedElementIndex
|
||||
* The expected selected element index.
|
||||
*/
|
||||
function assertHelpButtonSelected(expectedSelectedElementIndex) {
|
||||
assertSelection(
|
||||
expectedSelectedElementIndex,
|
||||
"urlbarView-button-help",
|
||||
"help button"
|
||||
);
|
||||
function assertButtonSelected(expectedSelectedElementIndex) {
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
assertSelection(
|
||||
expectedSelectedElementIndex,
|
||||
"urlbarView-button-menu",
|
||||
"menu button"
|
||||
);
|
||||
} else {
|
||||
assertSelection(
|
||||
expectedSelectedElementIndex,
|
||||
"urlbarView-button-help",
|
||||
"help button"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -389,5 +420,9 @@ function assertHelpButtonSelected(expectedSelectedElementIndex) {
|
|||
* A string to include in the assertion message.
|
||||
*/
|
||||
function assertOtherResultSelected(expectedSelectedElementIndex, msg) {
|
||||
assertSelection(expectedSelectedElementIndex, "urlbarView-row", msg);
|
||||
assertSelection(
|
||||
expectedSelectedElementIndex,
|
||||
UrlbarPrefs.get("resultMenu") ? "urlbarView-row-inner" : "urlbarView-row",
|
||||
msg
|
||||
);
|
||||
}
|
||||
|
|
|
@ -219,6 +219,11 @@ add_task(async function test_searchMode_removeRestyledHistory() {
|
|||
});
|
||||
|
||||
add_task(async function blockButton() {
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
// This case is covered by browser_result_menu.js.
|
||||
return;
|
||||
}
|
||||
|
||||
let url = "https://example.com/has-block-button";
|
||||
let provider = new UrlbarTestUtils.TestProvider({
|
||||
priority: Infinity,
|
||||
|
|
|
@ -7,41 +7,6 @@ add_setup(async function() {
|
|||
});
|
||||
});
|
||||
|
||||
async function openResultMenuAndPressAccesskey(resultIndex, accesskey) {
|
||||
let menuButton = UrlbarTestUtils.getButtonForResultIndex(
|
||||
window,
|
||||
"menu",
|
||||
resultIndex
|
||||
);
|
||||
ok(menuButton, `found the menu button at result index ${resultIndex}`);
|
||||
while (gURLBar.view.selectedRowIndex != resultIndex) {
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
}
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
is(
|
||||
UrlbarTestUtils.getSelectedElement(window),
|
||||
menuButton,
|
||||
`selected the menu button at result index ${resultIndex}`
|
||||
);
|
||||
|
||||
let promiseMenuOpen = BrowserTestUtils.waitForEvent(
|
||||
gURLBar.view.resultMenu,
|
||||
"popupshown"
|
||||
);
|
||||
EventUtils.synthesizeKey("KEY_Enter", {});
|
||||
info("waiting for the menu to open");
|
||||
await promiseMenuOpen;
|
||||
|
||||
info(`pressing access key (${accesskey}) to activate menu item`);
|
||||
let promiseCommand = BrowserTestUtils.waitForEvent(
|
||||
gURLBar.view.resultMenu,
|
||||
"command"
|
||||
);
|
||||
EventUtils.synthesizeKey(accesskey);
|
||||
info("waiting for command event");
|
||||
await promiseCommand;
|
||||
}
|
||||
|
||||
add_task(async function test_remove_history() {
|
||||
const TEST_URL = "https://remove.me/from_urlbar/";
|
||||
await PlacesTestUtils.addVisits(TEST_URL);
|
||||
|
@ -67,7 +32,9 @@ add_task(async function test_remove_history() {
|
|||
|
||||
let expectedResultCount = UrlbarTestUtils.getResultCount(window) - 1;
|
||||
|
||||
await openResultMenuAndPressAccesskey(resultIndex, "R");
|
||||
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "R", {
|
||||
resultIndex,
|
||||
});
|
||||
|
||||
const removeEvents = await promiseVisitRemoved;
|
||||
Assert.ok(
|
||||
|
@ -124,10 +91,13 @@ add_task(async function test_remove_search_history() {
|
|||
value: "foo",
|
||||
});
|
||||
|
||||
let index = 1;
|
||||
let resultIndex = 1;
|
||||
let count = UrlbarTestUtils.getResultCount(window);
|
||||
for (; index < count; index++) {
|
||||
let result = await UrlbarTestUtils.getDetailsOfResultAt(window, index);
|
||||
for (; resultIndex < count; resultIndex++) {
|
||||
let result = await UrlbarTestUtils.getDetailsOfResultAt(
|
||||
window,
|
||||
resultIndex
|
||||
);
|
||||
if (
|
||||
result.type == UrlbarUtils.RESULT_TYPE.SEARCH &&
|
||||
result.source == UrlbarUtils.RESULT_SOURCE.HISTORY
|
||||
|
@ -135,9 +105,11 @@ add_task(async function test_remove_search_history() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
Assert.ok(index < count, "Result found");
|
||||
Assert.ok(resultIndex < count, "Result found");
|
||||
|
||||
await openResultMenuAndPressAccesskey(index, "R");
|
||||
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "R", {
|
||||
resultIndex,
|
||||
});
|
||||
await promiseRemoved;
|
||||
|
||||
await TestUtils.waitForCondition(
|
||||
|
@ -224,13 +196,17 @@ add_task(async function firefoxSuggest() {
|
|||
|
||||
await openResults();
|
||||
let tabOpenPromise = BrowserTestUtils.waitForNewTab(gBrowser, helpUrl);
|
||||
await openResultMenuAndPressAccesskey(0, "L");
|
||||
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "L", {
|
||||
resultIndex: 0,
|
||||
});
|
||||
info("Waiting for help URL to load in a new tab");
|
||||
await tabOpenPromise;
|
||||
gBrowser.removeCurrentTab();
|
||||
|
||||
await openResults();
|
||||
await openResultMenuAndPressAccesskey(0, "D");
|
||||
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "D", {
|
||||
resultIndex: 0,
|
||||
});
|
||||
|
||||
Assert.equal(
|
||||
blockResultCallCount,
|
||||
|
|
|
@ -49,13 +49,19 @@ add_task(async function test() {
|
|||
value: "test",
|
||||
});
|
||||
|
||||
EventUtils.synthesizeKey("KEY_Tab", { repeat: 3 });
|
||||
EventUtils.synthesizeKey("KEY_Tab", {
|
||||
repeat: UrlbarPrefs.get("resultMenu") ? 5 : 3,
|
||||
});
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
ok(
|
||||
UrlbarTestUtils.getOneOffSearchButtons(window).selectedButton,
|
||||
"a one off button is selected"
|
||||
);
|
||||
|
||||
Assert.equal(selectionCount, 4, "We selected the four elements in the view.");
|
||||
Assert.equal(
|
||||
selectionCount,
|
||||
UrlbarPrefs.get("resultMenu") ? 6 : 4,
|
||||
"Number of elements selected in the view."
|
||||
);
|
||||
UrlbarProvidersManager.unregisterProvider(provider);
|
||||
});
|
||||
|
|
|
@ -297,13 +297,18 @@ async function expectTabThroughResults(options = { reverse: false }) {
|
|||
|
||||
for (let i = initiallySelectedIndex + 1; i < resultCount; i++) {
|
||||
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: options.reverse });
|
||||
if (UrlbarTestUtils.getButtonForResultIndex(window, "menu")) {
|
||||
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: options.reverse });
|
||||
}
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getSelectedRowIndex(window),
|
||||
options.reverse ? resultCount - i : i
|
||||
);
|
||||
}
|
||||
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
EventUtils.synthesizeKey("KEY_Tab", {
|
||||
repeat: UrlbarPrefs.get("resultMenu") && result.heuristic ? 2 : 1,
|
||||
});
|
||||
|
||||
if (!options.reverse) {
|
||||
Assert.equal(
|
||||
|
|
|
@ -97,7 +97,7 @@ add_task(async function basic() {
|
|||
"The correct action text is displayed in the tab-to-search result."
|
||||
);
|
||||
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getSelectedRowIndex(window),
|
||||
1,
|
||||
|
@ -142,7 +142,9 @@ add_task(async function activedescendant_tab() {
|
|||
"The second result is a tab-to-search result."
|
||||
);
|
||||
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
EventUtils.synthesizeKey("KEY_Tab", {
|
||||
repeat: UrlbarPrefs.get("resultMenu") ? 2 : 1,
|
||||
});
|
||||
|
||||
await UrlbarTestUtils.assertSearchMode(window, {
|
||||
engineName: TEST_ENGINE_NAME,
|
||||
|
@ -150,7 +152,7 @@ add_task(async function activedescendant_tab() {
|
|||
isPreview: true,
|
||||
});
|
||||
let aadID = gURLBar.inputField.getAttribute("aria-activedescendant");
|
||||
Assert.ok(!aadID, "aria-activedescendant was not set.");
|
||||
Assert.equal(aadID, null, "aria-activedescendant was not set.");
|
||||
|
||||
// Cycle through all the results then return to the tab-to-search result. It
|
||||
// should be announced.
|
||||
|
@ -159,10 +161,14 @@ add_task(async function activedescendant_tab() {
|
|||
let firstRow = await UrlbarTestUtils.waitForAutocompleteResultAt(window, 0);
|
||||
Assert.equal(
|
||||
aadID,
|
||||
firstRow.id,
|
||||
UrlbarTestUtils.getButtonForResultIndex(window, "menu", 0)
|
||||
? firstRow._content.id
|
||||
: firstRow.id,
|
||||
"aria-activedescendant was set to the row after the tab-to-search result."
|
||||
);
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
EventUtils.synthesizeKey("KEY_Tab", {
|
||||
repeat: UrlbarPrefs.get("resultMenu") ? 2 : 1,
|
||||
});
|
||||
aadID = gURLBar.inputField.getAttribute("aria-activedescendant");
|
||||
Assert.equal(
|
||||
aadID,
|
||||
|
@ -186,7 +192,9 @@ add_task(async function activedescendant_tab() {
|
|||
"The second result is a tab-to-search result."
|
||||
);
|
||||
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
EventUtils.synthesizeKey("KEY_Tab", {
|
||||
repeat: UrlbarPrefs.get("resultMenu") ? 2 : 1,
|
||||
});
|
||||
|
||||
await UrlbarTestUtils.assertSearchMode(window, {
|
||||
engineName: TEST_ENGINE_NAME,
|
||||
|
@ -194,7 +202,7 @@ add_task(async function activedescendant_tab() {
|
|||
isPreview: true,
|
||||
});
|
||||
aadID = gURLBar.inputField.getAttribute("aria-activedescendant");
|
||||
Assert.ok(!aadID, "aria-activedescendant was not set.");
|
||||
Assert.equal(aadID, null, "aria-activedescendant was not set.");
|
||||
|
||||
await UrlbarTestUtils.exitSearchMode(window);
|
||||
await UrlbarTestUtils.promisePopupClose(window, () => gURLBar.blur());
|
||||
|
@ -262,7 +270,7 @@ add_task(async function tab_key_race() {
|
|||
return;
|
||||
}
|
||||
info(
|
||||
"Test typing a letter followed shortly by Tab consistently selects a tab-to-search result"
|
||||
"Test typing a letter followed shortly by down arrow consistently selects a tab-to-search result"
|
||||
);
|
||||
Assert.equal(gURLBar.value, "", "Sanity check urlbar is empty");
|
||||
let promiseQueryStarted = new Promise(resolve => {
|
||||
|
@ -307,11 +315,11 @@ add_task(async function tab_key_race() {
|
|||
EventUtils.synthesizeKey(TEST_ENGINE_DOMAIN.slice(0, 1));
|
||||
info("Awaiting for the query to start");
|
||||
await promiseQueryStarted;
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
await UrlbarTestUtils.promiseSearchComplete(window);
|
||||
await TestUtils.waitForCondition(
|
||||
() => UrlbarTestUtils.getSelectedRowIndex(window) == 1,
|
||||
"Wait for tab key to be handled"
|
||||
"Wait for down arrow key to be handled"
|
||||
);
|
||||
await UrlbarTestUtils.assertSearchMode(window, {
|
||||
engineName: TEST_ENGINE_NAME,
|
||||
|
@ -342,7 +350,7 @@ add_task(async function onboard() {
|
|||
`https://${TEST_ENGINE_DOMAIN}/`,
|
||||
"The autofilled URL matches the engine domain."
|
||||
);
|
||||
EventUtils.synthesizeKey("KEY_Tab");
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getSelectedRowIndex(window),
|
||||
1,
|
||||
|
|
|
@ -339,9 +339,17 @@ add_task(async function buttons() {
|
|||
{
|
||||
url: mainResultUrl,
|
||||
helpUrl: mainResultHelpUrl,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: true,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
}
|
||||
),
|
||||
new UrlbarResult(
|
||||
|
@ -383,12 +391,26 @@ add_task(async function buttons() {
|
|||
JSON.stringify(rowUrls)
|
||||
);
|
||||
};
|
||||
let assertResultMenuOpen = () => {
|
||||
Assert.equal(
|
||||
gURLBar.view.resultMenu.state,
|
||||
"showing",
|
||||
"Result menu is open"
|
||||
);
|
||||
EventUtils.synthesizeKey("KEY_Escape");
|
||||
};
|
||||
|
||||
let testData = [
|
||||
{
|
||||
description: "Block button to block button",
|
||||
mousedown: ".urlbarView-row:nth-child(1) .urlbarView-button-block",
|
||||
afterMouseupCallback: assertBlockResultCalled,
|
||||
description: UrlbarPrefs.get("resultMenu")
|
||||
? "Menu button to menu button"
|
||||
: "Block button to block button",
|
||||
mousedown: UrlbarPrefs.get("resultMenu")
|
||||
? ".urlbarView-row:nth-child(1) .urlbarView-button-menu"
|
||||
: ".urlbarView-row:nth-child(1) .urlbarView-button-block",
|
||||
afterMouseupCallback: UrlbarPrefs.get("resultMenu")
|
||||
? assertResultMenuOpen
|
||||
: assertBlockResultCalled,
|
||||
expected: {
|
||||
mousedownSelected: false,
|
||||
topSites: {
|
||||
|
@ -402,6 +424,7 @@ add_task(async function buttons() {
|
|||
},
|
||||
},
|
||||
{
|
||||
skip: UrlbarPrefs.get("resultMenu"),
|
||||
description: "Help button to help button",
|
||||
mousedown: ".urlbarView-row:nth-child(1) .urlbarView-button-help",
|
||||
expected: {
|
||||
|
@ -411,25 +434,35 @@ add_task(async function buttons() {
|
|||
},
|
||||
},
|
||||
{
|
||||
description: "Row-inner to block button",
|
||||
description: UrlbarPrefs.get("resultMenu")
|
||||
? "Row-inner to menu button"
|
||||
: "Row-inner to block button",
|
||||
mousedown: ".urlbarView-row:nth-child(1) > .urlbarView-row-inner",
|
||||
mouseup: ".urlbarView-row:nth-child(1) .urlbarView-button-block",
|
||||
afterMouseupCallback: assertBlockResultCalled,
|
||||
mouseup: UrlbarPrefs.get("resultMenu")
|
||||
? ".urlbarView-row:nth-child(1) .urlbarView-button-menu"
|
||||
: ".urlbarView-row:nth-child(1) .urlbarView-button-block",
|
||||
afterMouseupCallback: UrlbarPrefs.get("resultMenu")
|
||||
? assertResultMenuOpen
|
||||
: assertBlockResultCalled,
|
||||
expected: {
|
||||
mousedownSelected: true,
|
||||
topSites: {
|
||||
pageProxyState: "invalid",
|
||||
value: otherResultUrl,
|
||||
value: UrlbarPrefs.get("resultMenu") ? initialTabUrl : otherResultUrl,
|
||||
},
|
||||
searchString: {
|
||||
pageProxyState: "invalid",
|
||||
value: otherResultUrl,
|
||||
value: UrlbarPrefs.get("resultMenu") ? searchString : otherResultUrl,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Block button to row-inner",
|
||||
mousedown: ".urlbarView-row:nth-child(1) .urlbarView-button-block",
|
||||
description: UrlbarPrefs.get("resultMenu")
|
||||
? "Menu button to row-inner"
|
||||
: "Block button to row-inner",
|
||||
mousedown: UrlbarPrefs.get("resultMenu")
|
||||
? ".urlbarView-row:nth-child(1) .urlbarView-button-menu"
|
||||
: ".urlbarView-row:nth-child(1) .urlbarView-button-block",
|
||||
mouseup: ".urlbarView-row:nth-child(1) > .urlbarView-row-inner",
|
||||
expected: {
|
||||
mousedownSelected: false,
|
||||
|
@ -440,9 +473,22 @@ add_task(async function buttons() {
|
|||
];
|
||||
|
||||
for (let showTopSites of [true, false]) {
|
||||
for (let { description, mousedown, mouseup, expected } of testData) {
|
||||
for (let {
|
||||
description,
|
||||
mousedown,
|
||||
mouseup,
|
||||
expected,
|
||||
afterMouseupCallback = null,
|
||||
skip = false,
|
||||
} of testData) {
|
||||
if (skip) {
|
||||
info(
|
||||
`Skipping test with showTopSites = ${showTopSites}: ${description}`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
info(`Running test with showTopSites = ${showTopSites}: ${description}`);
|
||||
mouseup = mouseup || mousedown;
|
||||
mouseup ||= mousedown;
|
||||
|
||||
await BrowserTestUtils.withNewTab(initialTabUrl, async () => {
|
||||
Assert.equal(
|
||||
|
@ -525,8 +571,8 @@ add_task(async function buttons() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (expected.afterMouseupCallback) {
|
||||
await expected.afterMouseupCallback();
|
||||
if (afterMouseupCallback) {
|
||||
await afterMouseupCallback();
|
||||
}
|
||||
|
||||
let state = showTopSites ? expected.topSites : expected.searchString;
|
||||
|
@ -551,7 +597,17 @@ async function waitForElements(selectors) {
|
|||
let elements;
|
||||
await BrowserTestUtils.waitForCondition(() => {
|
||||
elements = selectors.map(s => document.querySelector(s));
|
||||
return elements.every(e => e && BrowserTestUtils.is_visible(e));
|
||||
return elements.every(e => {
|
||||
if (e?.classList.contains("urlbarView-button-menu")) {
|
||||
// Hover the row to make the menu button visible.
|
||||
let row = e.closest(".urlbarView-row");
|
||||
EventUtils.synthesizeMouse(row, 1, 1, { type: "mouseover" });
|
||||
EventUtils.synthesizeMouse(row, 2, 2, { type: "mousemove" });
|
||||
EventUtils.synthesizeMouse(row, 3, 3, { type: "mousemove" });
|
||||
EventUtils.synthesizeMouse(row, 4, 4, { type: "mousemove" });
|
||||
}
|
||||
return e && BrowserTestUtils.is_visible(e);
|
||||
});
|
||||
}, "Waiting for elements to become visible: " + JSON.stringify(selectors));
|
||||
return elements;
|
||||
}
|
||||
|
|
|
@ -399,27 +399,35 @@ class _QuickSuggestTestUtils {
|
|||
"Result sponsored label"
|
||||
);
|
||||
|
||||
let helpButton = row._buttons.get("help");
|
||||
this.Assert.ok(helpButton, "The help button should be present");
|
||||
this.Assert.equal(
|
||||
result.payload.helpUrl,
|
||||
lazy.QuickSuggest.HELP_URL,
|
||||
"Result helpURL"
|
||||
);
|
||||
|
||||
let blockButton = row._buttons.get("block");
|
||||
if (!isBestMatch) {
|
||||
this.Assert.equal(
|
||||
!!blockButton,
|
||||
lazy.UrlbarPrefs.get("quickSuggestBlockingEnabled"),
|
||||
"The block button is present iff quick suggest blocking is enabled"
|
||||
if (lazy.UrlbarPrefs.get("resultMenu")) {
|
||||
this.Assert.ok(
|
||||
row._buttons.get("menu"),
|
||||
"The menu button should be present"
|
||||
);
|
||||
} else {
|
||||
this.Assert.equal(
|
||||
!!blockButton,
|
||||
lazy.UrlbarPrefs.get("bestMatchBlockingEnabled"),
|
||||
"The block button is present iff best match blocking is enabled"
|
||||
);
|
||||
let helpButton = row._buttons.get("help");
|
||||
this.Assert.ok(helpButton, "The help button should be present");
|
||||
|
||||
let blockButton = row._buttons.get("block");
|
||||
if (!isBestMatch) {
|
||||
this.Assert.equal(
|
||||
!!blockButton,
|
||||
lazy.UrlbarPrefs.get("quickSuggestBlockingEnabled"),
|
||||
"The block button is present iff quick suggest blocking is enabled"
|
||||
);
|
||||
} else {
|
||||
this.Assert.equal(
|
||||
!!blockButton,
|
||||
lazy.UrlbarPrefs.get("bestMatchBlockingEnabled"),
|
||||
"The block button is present iff best match blocking is enabled"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return details;
|
||||
|
|
|
@ -102,11 +102,17 @@ add_combo_task(async function basic_keyboard({ result, isBestMatch }) {
|
|||
await doBasicBlockTest({
|
||||
result,
|
||||
isBestMatch,
|
||||
block: () => {
|
||||
// TAB twice to select the block button: once to select the main
|
||||
// part of the row, once to select the block button.
|
||||
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
|
||||
EventUtils.synthesizeKey("KEY_Enter");
|
||||
block: async () => {
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "D", {
|
||||
resultIndex: 1,
|
||||
});
|
||||
} else {
|
||||
// TAB twice to select the block button: once to select the main
|
||||
// part of the row, once to select the block button.
|
||||
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
|
||||
EventUtils.synthesizeKey("KEY_Enter");
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
@ -116,8 +122,18 @@ add_combo_task(async function basic_mouse({ result, isBestMatch }) {
|
|||
await doBasicBlockTest({
|
||||
result,
|
||||
isBestMatch,
|
||||
block: blockButton => {
|
||||
EventUtils.synthesizeMouseAtCenter(blockButton, {});
|
||||
block: async () => {
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "D", {
|
||||
resultIndex: 1,
|
||||
openByMouse: true,
|
||||
});
|
||||
} else {
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
UrlbarTestUtils.getButtonForResultIndex(window, "block", 1),
|
||||
{}
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
@ -150,7 +166,7 @@ async function doBasicBlockTest({ result, isBestMatch, block }) {
|
|||
);
|
||||
|
||||
let isSponsored = result.keywords[0] == "sponsored";
|
||||
let details = await QuickSuggestTestUtils.assertIsQuickSuggest({
|
||||
await QuickSuggestTestUtils.assertIsQuickSuggest({
|
||||
window,
|
||||
isBestMatch,
|
||||
isSponsored,
|
||||
|
@ -158,8 +174,7 @@ async function doBasicBlockTest({ result, isBestMatch, block }) {
|
|||
});
|
||||
|
||||
// Block the suggestion.
|
||||
let blockButton = details.element.row._buttons.get("block");
|
||||
await block(blockButton);
|
||||
await block();
|
||||
|
||||
// The row should have been removed.
|
||||
Assert.ok(
|
||||
|
@ -268,8 +283,14 @@ add_task(async function blockMultiple() {
|
|||
});
|
||||
|
||||
// Block it.
|
||||
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
|
||||
EventUtils.synthesizeKey("KEY_Enter");
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
await UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "D", {
|
||||
resultIndex: 1,
|
||||
});
|
||||
} else {
|
||||
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
|
||||
EventUtils.synthesizeKey("KEY_Enter");
|
||||
}
|
||||
Assert.ok(
|
||||
await QuickSuggest.blockedSuggestions.has(url),
|
||||
"Suggestion is blocked after picking block button"
|
||||
|
@ -357,7 +378,6 @@ async function doDisabledTest({
|
|||
originalUrl: result.url,
|
||||
isSponsored: result.keywords[0] == "sponsored",
|
||||
});
|
||||
let blockButton = details.element.row._buttons.get("block");
|
||||
|
||||
// Arrow down to select the suggestion and press the key shortcut to block.
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
|
@ -372,7 +392,12 @@ async function doDisabledTest({
|
|||
(!isBestMatch && !quickSuggestBlockingEnabled)
|
||||
) {
|
||||
// Blocking is disabled. The key shortcut shouldn't have done anything.
|
||||
Assert.ok(!blockButton, "Block button is not present");
|
||||
if (!UrlbarPrefs.get("resultMenu")) {
|
||||
Assert.ok(
|
||||
!details.element.row._buttons.get("block"),
|
||||
"Block button is not present"
|
||||
);
|
||||
}
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getResultCount(window),
|
||||
expectedResultCount,
|
||||
|
@ -390,7 +415,12 @@ async function doDisabledTest({
|
|||
);
|
||||
} else {
|
||||
// Blocking is enabled. The suggestion should have been blocked.
|
||||
Assert.ok(blockButton, "Block button is present");
|
||||
if (!UrlbarPrefs.get("resultMenu")) {
|
||||
Assert.ok(
|
||||
details.element.row._buttons.get("block"),
|
||||
"Block button is present"
|
||||
);
|
||||
}
|
||||
Assert.equal(
|
||||
UrlbarTestUtils.getResultCount(window),
|
||||
1,
|
||||
|
|
|
@ -97,6 +97,15 @@ async function setUpTelemetryTest({
|
|||
merinoSuggestions = null,
|
||||
config = QuickSuggestTestUtils.DEFAULT_CONFIG,
|
||||
}) {
|
||||
if (UrlbarPrefs.get("resultMenu")) {
|
||||
todo(
|
||||
false,
|
||||
"telemetry for the result menu to be implemented in bug 1790020"
|
||||
);
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.urlbar.resultMenu", false]],
|
||||
});
|
||||
}
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
// Enable blocking on primary sponsored and nonsponsored suggestions so we
|
||||
|
|
|
@ -92,9 +92,17 @@ const EXPECTED_SPONSORED_RESULT = {
|
|||
sponsoredIabCategory: "22 - Shopping",
|
||||
isSponsored: true,
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: "http://test.com/q=frabbits",
|
||||
source: "remote-settings",
|
||||
},
|
||||
|
@ -117,9 +125,17 @@ const EXPECTED_NONSPONSORED_RESULT = {
|
|||
sponsoredIabCategory: "5 - Education",
|
||||
isSponsored: false,
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: "http://test.com/?q=nonsponsored",
|
||||
source: "remote-settings",
|
||||
},
|
||||
|
@ -142,9 +158,17 @@ const EXPECTED_HTTP_RESULT = {
|
|||
sponsoredIabCategory: "22 - Shopping",
|
||||
isSponsored: true,
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: "http://" + PREFIX_SUGGESTIONS_STRIPPED_URL,
|
||||
source: "remote-settings",
|
||||
},
|
||||
|
@ -167,9 +191,17 @@ const EXPECTED_HTTPS_RESULT = {
|
|||
sponsoredIabCategory: "22 - Shopping",
|
||||
isSponsored: true,
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: PREFIX_SUGGESTIONS_STRIPPED_URL,
|
||||
source: "remote-settings",
|
||||
},
|
||||
|
@ -948,9 +980,17 @@ add_task(async function dedupeAgainstURL_timestamps() {
|
|||
sponsoredIabCategory: "22 - Shopping",
|
||||
isSponsored: true,
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
source: "remote-settings",
|
||||
},
|
||||
};
|
||||
|
|
|
@ -63,9 +63,17 @@ const EXPECTED_BEST_MATCH_URLBAR_RESULT = {
|
|||
sponsoredBlockId: 1,
|
||||
sponsoredAdvertiser: "TestAdvertiser",
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: "http://example.com",
|
||||
source: "remote-settings",
|
||||
},
|
||||
|
@ -87,9 +95,17 @@ const EXPECTED_NON_BEST_MATCH_URLBAR_RESULT = {
|
|||
sponsoredBlockId: 1,
|
||||
sponsoredAdvertiser: "TestAdvertiser",
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: "http://example.com",
|
||||
source: "remote-settings",
|
||||
},
|
||||
|
@ -111,9 +127,17 @@ const EXPECTED_BEST_MATCH_POSITION_URLBAR_RESULT = {
|
|||
sponsoredBlockId: 2,
|
||||
sponsoredAdvertiser: "TestAdvertiser",
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: "http://example.com/best-match-position",
|
||||
source: "remote-settings",
|
||||
},
|
||||
|
|
|
@ -52,9 +52,17 @@ const EXPECTED_SPONSORED_URLBAR_RESULT = {
|
|||
sponsoredAdvertiser: "TestAdvertiser",
|
||||
sponsoredIabCategory: "22 - Shopping",
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
source: "remote-settings",
|
||||
},
|
||||
};
|
||||
|
@ -77,9 +85,17 @@ const EXPECTED_NONSPONSORED_URLBAR_RESULT = {
|
|||
sponsoredAdvertiser: "TestAdvertiser",
|
||||
sponsoredIabCategory: "5 - Education",
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
source: "remote-settings",
|
||||
},
|
||||
};
|
||||
|
|
|
@ -41,9 +41,17 @@ const EXPECTED_REMOTE_SETTINGS_URLBAR_RESULT = {
|
|||
sponsoredAdvertiser: "TestAdvertiser",
|
||||
isSponsored: true,
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: "http://test.com/q=frabbits",
|
||||
source: "remote-settings",
|
||||
},
|
||||
|
@ -65,9 +73,17 @@ const EXPECTED_MERINO_URLBAR_RESULT = {
|
|||
sponsoredAdvertiser: "advertiser",
|
||||
isSponsored: true,
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: "url",
|
||||
requestId: "request_id",
|
||||
source: "merino",
|
||||
|
@ -463,9 +479,17 @@ add_task(async function multipleMerinoSuggestions() {
|
|||
sponsoredAdvertiser: "multipleMerinoSuggestions 1 advertiser",
|
||||
isSponsored: true,
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: "multipleMerinoSuggestions 1 url",
|
||||
requestId: "request_id",
|
||||
source: "merino",
|
||||
|
@ -682,9 +706,17 @@ add_task(async function topPick() {
|
|||
sponsoredAdvertiser: "multipleMerinoSuggestions 2 advertiser",
|
||||
isSponsored: true,
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: "multipleMerinoSuggestions 2 url",
|
||||
requestId: "request_id",
|
||||
source: "merino",
|
||||
|
|
|
@ -188,9 +188,17 @@ add_task(async function() {
|
|||
sponsoredIabCategory: qsResult.iab_category,
|
||||
icon: null,
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
source: "remote-settings",
|
||||
},
|
||||
});
|
||||
|
|
|
@ -157,9 +157,17 @@ function createExpectedQuickSuggestResult(suggest) {
|
|||
sponsoredIabCategory: suggest.iab_category,
|
||||
isSponsored: suggest.iab_category !== "5 - Education",
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: { id: "firefox-suggest-urlbar-learn-more" },
|
||||
helpL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: false,
|
||||
blockL10n: { id: "firefox-suggest-urlbar-block" },
|
||||
blockL10n: {
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
displayUrl: suggest.url,
|
||||
source: "remote-settings",
|
||||
},
|
||||
|
|
|
@ -762,11 +762,15 @@ function makeExpectedResult(temperatureUnit = undefined) {
|
|||
iconId: "6",
|
||||
helpUrl: QuickSuggest.HELP_URL,
|
||||
helpL10n: {
|
||||
id: "firefox-suggest-urlbar-learn-more",
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-learn-more-about-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-learn-more",
|
||||
},
|
||||
isBlockable: true,
|
||||
blockL10n: {
|
||||
id: "firefox-suggest-urlbar-block",
|
||||
id: UrlbarPrefs.get("resultMenu")
|
||||
? "urlbar-result-menu-dismiss-firefox-suggest"
|
||||
: "firefox-suggest-urlbar-block",
|
||||
},
|
||||
requestId: MerinoTestUtils.server.response.body.request_id,
|
||||
source: "merino",
|
||||
|
|
|
@ -117,6 +117,9 @@ urlbar-result-menu-button =
|
|||
urlbar-result-menu-remove-from-history =
|
||||
.label = Remove from history
|
||||
.accesskey = R
|
||||
urlbar-result-menu-tip-get-help =
|
||||
.label = Get help
|
||||
.accesskey = h
|
||||
|
||||
## Prompts users to use the Urlbar when they open a new tab or visit the
|
||||
## homepage of their default search engine.
|
||||
|
|
Загрузка…
Ссылка в новой задаче