Bug 1692330 - Hide the 'Add a keyword for this search' when inside of a login form. r=Gijs

Differential Revision: https://phabricator.services.mozilla.com/D106314
This commit is contained in:
Jared Wein 2021-02-25 12:15:23 +00:00
parent 86db2fec08
commit 8f326f38b5
4 changed files with 250 additions and 19 deletions

View File

@ -681,10 +681,7 @@ class nsContextMenu {
(this.onLink && !this.onMailtoLink && !this.onMozExtLink) ||
this.onPlainTextLink
);
this.showItem(
"context-keywordfield",
this.onTextInput && this.onKeywordField
);
this.showItem("context-keywordfield", this.shouldShowAddKeyword());
this.showItem("frame", this.inFrame);
if (this.inFrame) {
@ -809,7 +806,8 @@ class nsContextMenu {
);
this.showItem(
"context-sep-selectall",
!this.inAboutDevtoolsToolbox && this.isContentSelected
!this.inAboutDevtoolsToolbox &&
(this.isContentSelected || this.shouldShowAddKeyword())
);
// XXX dr
@ -956,19 +954,9 @@ class nsContextMenu {
let showGenerate = false;
let enableGeneration = Services.logins.isLoggedIn;
try {
let loginFillInfo = this.contentData && this.contentData.loginFillInfo;
let documentURI = this.contentData.documentURIObject;
// If we could not find a password field we
// don't want to show the form fill option.
if (
!loginFillInfo ||
!loginFillInfo.passwordField.found ||
documentURI.schemeIs("about") ||
this.browser.contentPrincipal.spec ==
"resource://pdf.js/web/viewer.html"
) {
// Both generation and fill will default to disabled.
if (!this.isLoginForm()) {
return;
}
showFill = true;
@ -976,10 +964,11 @@ class nsContextMenu {
// Disable the fill option if the user hasn't unlocked with their master password
// or if the password field or target field are disabled.
// XXX: Bug 1529025 to maybe respect signon.rememberSignons.
let loginFillInfo = this.contentData?.loginFillInfo;
let disableFill =
!Services.logins.isLoggedIn ||
loginFillInfo.passwordField.disabled ||
loginFillInfo.activeField.disabled;
loginFillInfo?.passwordField.disabled ||
loginFillInfo?.activeField.disabled;
this.setItemAttr("fill-login", "disabled", disableFill);
let onPasswordLikeField = PASSWORD_FIELDNAME_HINTS.includes(
@ -1002,7 +991,8 @@ class nsContextMenu {
);
}
let formOrigin = LoginHelper.getLoginOrigin(documentURI.spec);
let documentURI = this.contentData?.documentURIObject;
let formOrigin = LoginHelper.getLoginOrigin(documentURI?.spec);
let isGeneratedPasswordEnabled =
LoginHelper.generationAvailable && LoginHelper.generationEnabled;
showGenerate =
@ -1097,6 +1087,19 @@ class nsContextMenu {
);
}
isLoginForm() {
let loginFillInfo = this.contentData?.loginFillInfo;
let documentURI = this.contentData?.documentURIObject;
// If we could not find a password field then
// don't treat this as a login form.
return (
loginFillInfo?.passwordField?.found &&
!documentURI?.schemeIs("about") &&
this.browser.contentPrincipal.spec != "resource://pdf.js/web/viewer.html"
);
}
inspectNode() {
return nsContextMenu.DevToolsShim.inspectNode(
gBrowser.selectedTab,
@ -1925,6 +1928,10 @@ class nsContextMenu {
return false;
}
shouldShowAddKeyword() {
return this.onTextInput && this.onKeywordField && !this.isLoginForm();
}
addDictionaries() {
var uri = formatURL("browser.dictionaries.download.url", true);

View File

@ -6,6 +6,7 @@ support-files =
test_contextmenu_links.html
subtst_contextmenu.html
subtst_contextmenu_input.html
subtst_contextmenu_keyword.html
subtst_contextmenu_xul.xhtml
ctxmenu-image.png
../general/head.js
@ -14,6 +15,8 @@ support-files =
../../../../../toolkit/components/pdfjs/test/file_pdfjs_test.pdf
contextmenu_common.js
[browser_contextmenu_keyword.js]
skip-if = toolkit == "gtk" || (os == "win" && processor == "aarch64") # disabled on Linux due to bug 513558, aarch64 due to 1533161
[browser_contextmenu_loadblobinnewtab.js]
support-files = browser_contextmenu_loadblobinnewtab.html
[browser_contextmenu_save_blocked.js]

View File

@ -0,0 +1,204 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
let contextMenu;
const example_base =
"http://example.com/browser/browser/base/content/test/contextMenu/";
const MAIN_URL = example_base + "subtst_contextmenu_keyword.html";
add_task(async function test_setup() {
await BrowserTestUtils.openNewForegroundTab(gBrowser, MAIN_URL);
const chrome_base =
"chrome://mochitests/content/browser/browser/base/content/test/contextMenu/";
const contextmenu_common = chrome_base + "contextmenu_common.js";
/* import-globals-from contextmenu_common.js */
Services.scriptloader.loadSubScript(contextmenu_common, this);
// Ensure screenshots is really disabled (bug 1498738)
const addon = await AddonManager.getAddonByID("screenshots@mozilla.org");
await addon.disable({ allowSystemAddons: true });
});
add_task(async function test_text_input_spellcheck_noform() {
await test_contextmenu(
"#input_text_no_form",
[
"context-undo",
false,
"---",
null,
"context-cut",
null, // ignore the enabled/disabled states; there are race conditions
// in the edit commands but they're not relevant for what we're testing.
"context-copy",
null,
"context-paste",
null, // ignore clipboard state
"context-delete",
null,
"context-selectall",
null,
"---",
null,
"spell-check-enabled",
true,
"spell-dictionaries",
true,
[
"spell-check-dictionary-en-US",
true,
"---",
null,
"spell-add-dictionaries",
true,
],
null,
],
{
waitForSpellCheck: true,
async preCheckContextMenuFn() {
await SpecialPowers.spawn(
gBrowser.selectedBrowser,
[],
async function() {
let doc = content.document;
let input = doc.getElementById("input_text_no_form");
input.setAttribute("spellcheck", "true");
input.clientTop; // force layout flush
}
);
},
}
);
});
add_task(async function test_text_input_spellcheck_loginform() {
await test_contextmenu(
"#login_text",
[
"fill-login",
null,
[
"fill-login-no-logins",
false,
"---",
null,
"fill-login-saved-passwords",
true,
],
null,
"---",
null,
"context-undo",
false,
"---",
null,
"context-cut",
null, // ignore the enabled/disabled states; there are race conditions
// in the edit commands but they're not relevant for what we're testing.
"context-copy",
null,
"context-paste",
null, // ignore clipboard state
"context-delete",
null,
"context-selectall",
null,
"---",
null,
"spell-check-enabled",
true,
"spell-dictionaries",
true,
[
"spell-check-dictionary-en-US",
true,
"---",
null,
"spell-add-dictionaries",
true,
],
null,
],
{
waitForSpellCheck: true,
async preCheckContextMenuFn() {
await SpecialPowers.spawn(
gBrowser.selectedBrowser,
[],
async function() {
let doc = content.document;
let input = doc.getElementById("login_text");
input.setAttribute("spellcheck", "true");
input.clientTop; // force layout flush
}
);
},
}
);
});
add_task(async function test_text_input_spellcheck_searchform() {
await test_contextmenu(
"#search_text",
[
"context-undo",
false,
"---",
null,
"context-cut",
null, // ignore the enabled/disabled states; there are race conditions
// in the edit commands but they're not relevant for what we're testing.
"context-copy",
null,
"context-paste",
null, // ignore clipboard state
"context-delete",
null,
"context-selectall",
null,
"---",
null,
"context-keywordfield",
null,
"---",
null,
"spell-check-enabled",
true,
"spell-dictionaries",
true,
[
"spell-check-dictionary-en-US",
true,
"---",
null,
"spell-add-dictionaries",
true,
],
null,
],
{
waitForSpellCheck: true,
async preCheckContextMenuFn() {
await SpecialPowers.spawn(
gBrowser.selectedBrowser,
[],
async function() {
let doc = content.document;
let input = doc.getElementById("search_text");
input.setAttribute("spellcheck", "true");
input.clientTop; // force layout flush
}
);
},
}
);
});
add_task(async function test_cleanup() {
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Subtest for browser context menu</title>
</head>
<body>
Browser context menu subtest.
<input id="input_text_no_form">
<form id="form_with_password">
<input id="login_text">
<input id="input_password" type="password">
</form>
<form id="form_without_password">
<input id="search_text">
</form>
</body>
</html>