mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1188719 - Show login fill context menu on username field. r=MattN
This commit is contained in:
parent
5b91030628
commit
9439916e5f
@ -419,8 +419,14 @@
|
||||
oncommand="gContextMenu.switchPageDirection();"/>
|
||||
<menuseparator id="fill-login-separator" hidden="true"/>
|
||||
<menu id="fill-login"
|
||||
label="&fillPasswordMenu.label;"
|
||||
accesskey="&fillPasswordMenu.accesskey;"
|
||||
label="&fillLoginMenu.label;"
|
||||
label-login="&fillLoginMenu.label;"
|
||||
label-password="&fillPasswordMenu.label;"
|
||||
label-username="&fillUsernameMenu.label;"
|
||||
accesskey="&fillLoginMenu.accesskey;"
|
||||
accesskey-login="&fillLoginMenu.accesskey;"
|
||||
accesskey-password="&fillPasswordMenu.accesskey;"
|
||||
accesskey-username="&fillUsernameMenu.accesskey;"
|
||||
hidden="true">
|
||||
<menupopup id="fill-login-popup">
|
||||
<menuitem id="fill-login-no-logins"
|
||||
|
@ -107,6 +107,7 @@ let handleContentContextMenu = function (event) {
|
||||
let frameOuterWindowID = doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils)
|
||||
.outerWindowID;
|
||||
let loginFillInfo = LoginManagerContent.getFieldContext(event.target);
|
||||
|
||||
// get referrer attribute from clicked link and parse it
|
||||
// if per element referrer is enabled, the element referrer overrules
|
||||
@ -168,7 +169,8 @@ let handleContentContextMenu = function (event) {
|
||||
{ editFlags, spellInfo, customMenuItems, addonInfo,
|
||||
principal, docLocation, charSet, baseURI, referrer,
|
||||
referrerPolicy, contentType, contentDisposition,
|
||||
frameOuterWindowID, selectionInfo, disableSetDesktopBg },
|
||||
frameOuterWindowID, selectionInfo, disableSetDesktopBg,
|
||||
loginFillInfo, },
|
||||
{ event, popupNode: event.target });
|
||||
}
|
||||
else {
|
||||
@ -190,6 +192,7 @@ let handleContentContextMenu = function (event) {
|
||||
contentDisposition: contentDisposition,
|
||||
selectionInfo: selectionInfo,
|
||||
disableSetDesktopBackground: disableSetDesktopBg,
|
||||
loginFillInfo,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -506,13 +506,35 @@ nsContextMenu.prototype = {
|
||||
},
|
||||
|
||||
initPasswordManagerItems: function() {
|
||||
let showFillPassword = this.onPassword;
|
||||
let disableFillPassword = !Services.logins.isLoggedIn || this.target.disabled || this.target.readOnly;
|
||||
this.showItem("fill-login-separator", showFillPassword);
|
||||
this.showItem("fill-login", showFillPassword);
|
||||
this.setItemAttr("fill-login", "disabled", disableFillPassword);
|
||||
let loginFillInfo = gContextMenuContentData && gContextMenuContentData.loginFillInfo;
|
||||
|
||||
if (!showFillPassword || disableFillPassword) {
|
||||
// If we could not find a password field we
|
||||
// don't want to show the form fill option.
|
||||
let showFill = loginFillInfo && loginFillInfo.passwordField.found;
|
||||
|
||||
// Disable the fill option if the user has set a master password
|
||||
// or if the password field or target field are disabled.
|
||||
let disableFill = !loginFillInfo ||
|
||||
!Services.logins ||
|
||||
!Services.logins.isLoggedIn ||
|
||||
loginFillInfo.passwordField.disabled ||
|
||||
(!this.onPassword && loginFillInfo.usernameField.disabled);
|
||||
|
||||
this.showItem("fill-login-separator", showFill);
|
||||
this.showItem("fill-login", showFill);
|
||||
this.setItemAttr("fill-login", "disabled", disableFill);
|
||||
|
||||
// Set the correct label for the fill menu
|
||||
let fillMenu = document.getElementById("fill-login");
|
||||
if (this.onPassword) {
|
||||
fillMenu.setAttribute("label", fillMenu.getAttribute("label-password"));
|
||||
fillMenu.setAttribute("accesskey", fillMenu.getAttribute("accesskey-password"));
|
||||
} else {
|
||||
fillMenu.setAttribute("label", fillMenu.getAttribute("label-login"));
|
||||
fillMenu.setAttribute("accesskey", fillMenu.getAttribute("accesskey-login"));
|
||||
}
|
||||
|
||||
if (!showFill || disableFill) {
|
||||
return;
|
||||
}
|
||||
let documentURI = gContextMenuContentData.documentURIObject;
|
||||
|
@ -4056,6 +4056,7 @@
|
||||
frameOuterWindowID: aMessage.data.frameOuterWindowID,
|
||||
selectionInfo: aMessage.data.selectionInfo,
|
||||
disableSetDesktopBackground: aMessage.data.disableSetDesktopBg,
|
||||
loginFillInfo: aMessage.data.loginFillInfo,
|
||||
};
|
||||
let popup = browser.ownerDocument.getElementById("contentAreaContextMenu");
|
||||
let event = gContextMenuContentData.event;
|
||||
|
@ -476,7 +476,9 @@ var LoginManagerContent = {
|
||||
// If we have a target input, fills it's form.
|
||||
if (inputElement) {
|
||||
form = FormLikeFactory.createFromField(inputElement);
|
||||
clobberUsername = false;
|
||||
if (inputElement.type == "password") {
|
||||
clobberUsername = false;
|
||||
}
|
||||
}
|
||||
this._fillForm(form, true, clobberUsername, true, true, loginsFound, recipes, options);
|
||||
},
|
||||
@ -812,8 +814,11 @@ var LoginManagerContent = {
|
||||
*
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {bool} autofillForm denotes if we should fill the form in automatically
|
||||
* @param {bool} clobberUsername controls if an existing username can be
|
||||
* overwritten
|
||||
* @param {bool} clobberUsername controls if an existing username can be overwritten.
|
||||
* If this is false and an inputElement of type password
|
||||
* is also passed, the username field will be ignored.
|
||||
* If this is false and no inputElement is passed, if the username
|
||||
* field value is not found in foundLogins, it will not fill the password.
|
||||
* @param {bool} clobberPassword controls if an existing password value can be
|
||||
* overwritten
|
||||
* @param {bool} userTriggered is an indication of whether this filling was triggered by
|
||||
@ -867,11 +872,16 @@ var LoginManagerContent = {
|
||||
// the same as the one heuristically found, use the parameter
|
||||
// one instead.
|
||||
if (inputElement) {
|
||||
if (inputElement.type != "password") {
|
||||
if (inputElement.type == "password") {
|
||||
passwordField = inputElement;
|
||||
if (!clobberUsername) {
|
||||
usernameField = null;
|
||||
}
|
||||
} else if (LoginHelper.isUsernameFieldType(inputElement)) {
|
||||
usernameField = inputElement;
|
||||
} else {
|
||||
throw new Error("Unexpected input element type.");
|
||||
}
|
||||
passwordField = inputElement;
|
||||
usernameField = null;
|
||||
}
|
||||
|
||||
// Need a valid password field to do anything.
|
||||
@ -1031,6 +1041,53 @@ var LoginManagerContent = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Verify if a field is a valid login form field and
|
||||
* returns some information about it's FormLike.
|
||||
*
|
||||
* @param {Element} aField
|
||||
* A form field we want to verify.
|
||||
*
|
||||
* @returns {Object} an object with information about the
|
||||
* FormLike username and password field
|
||||
* or null if the passed field is invalid.
|
||||
*/
|
||||
getFieldContext(aField) {
|
||||
// If the element is not a proper form field, return null.
|
||||
if (!(aField instanceof Ci.nsIDOMHTMLInputElement) ||
|
||||
(aField.type != "password" && !LoginHelper.isUsernameFieldType(aField)) ||
|
||||
!aField.ownerDocument) {
|
||||
return null;
|
||||
}
|
||||
let form = FormLikeFactory.createFromField(aField);
|
||||
|
||||
let doc = aField.ownerDocument;
|
||||
let messageManager = messageManagerFromWindow(doc.defaultView);
|
||||
let recipes = messageManager.sendSyncMessage("RemoteLogins:findRecipes", {
|
||||
formOrigin: LoginUtils._getPasswordOrigin(doc.documentURI),
|
||||
})[0];
|
||||
|
||||
let [usernameField, newPasswordField, oldPasswordField] =
|
||||
this._getFormFields(form, false, recipes);
|
||||
|
||||
// If we are not verifying a password field, we want
|
||||
// to use aField as the username field.
|
||||
if (aField.type != "password") {
|
||||
usernameField = aField;
|
||||
}
|
||||
|
||||
return {
|
||||
usernameField: {
|
||||
found: !!usernameField,
|
||||
disabled: usernameField && (usernameField.disabled || usernameField.readOnly),
|
||||
},
|
||||
passwordField: {
|
||||
found: !!newPasswordField,
|
||||
disabled: newPasswordField && (newPasswordField.disabled || newPasswordField.readOnly),
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
var LoginUtils = {
|
||||
|
@ -60,7 +60,7 @@ let LoginManagerContextMenu = {
|
||||
|
||||
// login is bound so we can keep the reference to each object.
|
||||
item.addEventListener("command", function(login, event) {
|
||||
this._fillPassword(login, inputElement, browser, documentURI);
|
||||
this._fillTargetField(login, inputElement, browser, documentURI);
|
||||
}.bind(this, login));
|
||||
|
||||
fragment.appendChild(item);
|
||||
@ -151,7 +151,7 @@ let LoginManagerContextMenu = {
|
||||
* This isn't the same as the browser's top-level
|
||||
* document URI when subframes are involved.
|
||||
*/
|
||||
_fillPassword(login, inputElement, browser, documentURI) {
|
||||
_fillTargetField(login, inputElement, browser, documentURI) {
|
||||
LoginManagerParent.fillForm({
|
||||
browser: browser,
|
||||
loginFormOrigin: documentURI.prePath,
|
||||
|
Loading…
Reference in New Issue
Block a user