зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1567175, make LoginManagerContent and LoginManagerParent JS classes,r=MattN
Differential Revision: https://phabricator.services.mozilla.com/D47823 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
c5df88ff8f
Коммит
3302428083
|
@ -561,9 +561,9 @@ class ContextMenuChild extends JSWindowActorChild {
|
|||
} = doc;
|
||||
docLocation = docLocation && docLocation.spec;
|
||||
let frameOuterWindowID = WebNavigationFrames.getFrameId(doc.defaultView);
|
||||
let loginFillInfo = LoginManagerContent.getFieldContext(
|
||||
aEvent.composedTarget
|
||||
);
|
||||
let loginFillInfo = LoginManagerContent.forWindow(
|
||||
doc.defaultView
|
||||
).getFieldContext(aEvent.composedTarget);
|
||||
|
||||
// The same-origin check will be done in nsContextMenu.openLinkInTab.
|
||||
let parentAllowsMixedContent = !!this.docShell.mixedContentChannel;
|
||||
|
|
|
@ -45,13 +45,13 @@ addEventListener("DOMFormBeforeSubmit", function(event) {
|
|||
if (shouldIgnoreLoginManagerEvent(event)) {
|
||||
return;
|
||||
}
|
||||
LoginManagerContent.onDOMFormBeforeSubmit(event);
|
||||
this.LoginManagerContent.forWindow(content).onDOMFormBeforeSubmit(event);
|
||||
});
|
||||
addEventListener("DOMFormHasPassword", function(event) {
|
||||
if (shouldIgnoreLoginManagerEvent(event)) {
|
||||
return;
|
||||
}
|
||||
LoginManagerContent.onDOMFormHasPassword(event);
|
||||
this.LoginManagerContent.forWindow(content).onDOMFormHasPassword(event);
|
||||
let formLike = LoginFormFactory.createFromForm(event.originalTarget);
|
||||
InsecurePasswordUtils.reportInsecurePasswords(formLike);
|
||||
});
|
||||
|
@ -59,7 +59,10 @@ addEventListener("DOMInputPasswordAdded", function(event) {
|
|||
if (shouldIgnoreLoginManagerEvent(event)) {
|
||||
return;
|
||||
}
|
||||
LoginManagerContent.onDOMInputPasswordAdded(event, content);
|
||||
this.LoginManagerContent.forWindow(content).onDOMInputPasswordAdded(
|
||||
event,
|
||||
content
|
||||
);
|
||||
let formLike = LoginFormFactory.createFromField(event.originalTarget);
|
||||
InsecurePasswordUtils.reportInsecurePasswords(formLike);
|
||||
});
|
||||
|
|
|
@ -228,7 +228,7 @@ BrowserCLH.prototype = {
|
|||
if (shouldIgnoreLoginManagerEvent(event)) {
|
||||
return;
|
||||
}
|
||||
this.LoginManagerContent.onDOMFormBeforeSubmit(event);
|
||||
this.LoginManagerContent.forWindow(aWindow).onDOMFormBeforeSubmit(event);
|
||||
});
|
||||
aWindow.addEventListener(
|
||||
"DOMFormHasPassword",
|
||||
|
@ -236,7 +236,7 @@ BrowserCLH.prototype = {
|
|||
if (shouldIgnoreLoginManagerEvent(event)) {
|
||||
return;
|
||||
}
|
||||
this.LoginManagerContent.onDOMFormHasPassword(event);
|
||||
this.LoginManagerContent.forWindow(aWindow).onDOMFormHasPassword(event);
|
||||
},
|
||||
options
|
||||
);
|
||||
|
@ -247,7 +247,7 @@ BrowserCLH.prototype = {
|
|||
if (shouldIgnoreLoginManagerEvent(event)) {
|
||||
return;
|
||||
}
|
||||
this.LoginManagerContent.onDOMInputPasswordAdded(
|
||||
this.LoginManagerContent.forWindow(aWindow).onDOMInputPasswordAdded(
|
||||
event,
|
||||
event.target.ownerGlobal.top
|
||||
);
|
||||
|
@ -260,7 +260,7 @@ BrowserCLH.prototype = {
|
|||
event => {
|
||||
// XXXbz what about non-HTML documents??
|
||||
if (ChromeUtils.getClassName(event.target) == "HTMLDocument") {
|
||||
this.LoginManagerContent.onPageShow(event);
|
||||
this.LoginManagerContent.forWindow(aWindow).onPageShow(event);
|
||||
}
|
||||
},
|
||||
options
|
||||
|
|
|
@ -152,9 +152,9 @@ class GeckoViewAutofill {
|
|||
}
|
||||
}
|
||||
|
||||
const [usernameField] = LoginManagerContent.getUserNameAndPasswordFields(
|
||||
passwordField || aFormLike.elements[0]
|
||||
);
|
||||
const [usernameField] = LoginManagerContent.forWindow(
|
||||
window
|
||||
).getUserNameAndPasswordFields(passwordField || aFormLike.elements[0]);
|
||||
|
||||
const rootInfo = getInfo(aFormLike.rootElement, null, undefined, null);
|
||||
rootInfo.root = rootInfo.id;
|
||||
|
|
|
@ -505,7 +505,8 @@ LoginAutoComplete.prototype = {
|
|||
previousResult = null;
|
||||
}
|
||||
|
||||
let acLookupPromise = (this._autoCompleteLookupPromise = LoginManagerContent._autoCompleteSearchAsync(
|
||||
let loginManager = LoginManagerContent.forWindow(aElement.ownerGlobal);
|
||||
let acLookupPromise = (this._autoCompleteLookupPromise = loginManager._autoCompleteSearchAsync(
|
||||
aSearchString,
|
||||
previousResult,
|
||||
aElement
|
||||
|
|
|
@ -74,9 +74,9 @@ ChromeUtils.defineModuleGetter(
|
|||
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
this,
|
||||
"gNetUtil",
|
||||
"@mozilla.org/network/util;1",
|
||||
"nsINetUtil"
|
||||
"gFormFillService",
|
||||
"@mozilla.org/satchel/form-fill-controller;1",
|
||||
"nsIFormFillController"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "log", () => {
|
||||
|
@ -88,6 +88,13 @@ Services.cpmm.addMessageListener("clearRecipeCache", () => {
|
|||
LoginRecipesContent._clearRecipeCache();
|
||||
});
|
||||
|
||||
let gLoginManagerContentSingleton = null;
|
||||
|
||||
let _messages = [
|
||||
"PasswordManager:loginsFound",
|
||||
"PasswordManager:loginsAutoCompleted",
|
||||
];
|
||||
|
||||
let gLastRightClickTimeStamp = Number.NEGATIVE_INFINITY;
|
||||
|
||||
const observer = {
|
||||
|
@ -113,7 +120,9 @@ const observer = {
|
|||
aWebProgress.DOMWindow.document
|
||||
);
|
||||
|
||||
LoginManagerContent._onNavigation(aWebProgress.DOMWindow.document);
|
||||
LoginManagerContent.forWindow(aWebProgress.DOMWindow)._onNavigation(
|
||||
aWebProgress.DOMWindow.document
|
||||
);
|
||||
},
|
||||
|
||||
onStateChange(aWebProgress, aRequest, aState, aStatus) {
|
||||
|
@ -123,7 +132,9 @@ const observer = {
|
|||
) {
|
||||
// Re-fill a document restored from bfcache since password field values
|
||||
// aren't persisted there.
|
||||
LoginManagerContent._onDocumentRestored(aWebProgress.DOMWindow.document);
|
||||
LoginManagerContent.forWindow(aWebProgress.DOMWindow)._onDocumentRestored(
|
||||
aWebProgress.DOMWindow.document
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -156,7 +167,9 @@ const observer = {
|
|||
}
|
||||
|
||||
log("onStateChange handled:", channel);
|
||||
LoginManagerContent._onNavigation(aWebProgress.DOMWindow.document);
|
||||
LoginManagerContent.forWindow(aWebProgress.DOMWindow)._onNavigation(
|
||||
aWebProgress.DOMWindow.document
|
||||
);
|
||||
},
|
||||
|
||||
// nsIObserver
|
||||
|
@ -169,22 +182,25 @@ const observer = {
|
|||
break;
|
||||
}
|
||||
|
||||
let { focusedInput } = LoginManagerContent._formFillService;
|
||||
let { focusedInput } = gFormFillService;
|
||||
if (focusedInput.nodePrincipal.isNullPrincipal) {
|
||||
// If we have a null principal then prevent any more password manager code from running and
|
||||
// incorrectly using the document `location`.
|
||||
return;
|
||||
}
|
||||
|
||||
let window = focusedInput.ownerGlobal;
|
||||
let loginManagerContent = LoginManagerContent.forWindow(window);
|
||||
|
||||
let style = input.controller.getStyleAt(selectedIndex);
|
||||
if (style == "login" || style == "loginWithOrigin") {
|
||||
let details = JSON.parse(
|
||||
input.controller.getCommentAt(selectedIndex)
|
||||
);
|
||||
LoginManagerContent.onFieldAutoComplete(focusedInput, details.guid);
|
||||
loginManagerContent.onFieldAutoComplete(focusedInput, details.guid);
|
||||
} else if (style == "generatedPassword") {
|
||||
LoginManagerContent._highlightFilledField(focusedInput);
|
||||
LoginManagerContent._generatedPasswordFilledOrEdited(focusedInput);
|
||||
loginManagerContent._highlightFilledField(focusedInput);
|
||||
loginManagerContent._generatedPasswordFilledOrEdited(focusedInput);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -201,23 +217,32 @@ const observer = {
|
|||
return;
|
||||
}
|
||||
|
||||
let window = aEvent.target.ownerDocument.defaultView;
|
||||
|
||||
switch (aEvent.type) {
|
||||
// Used to mask fields with filled generated passwords when blurred.
|
||||
case "blur": {
|
||||
let unmask = false;
|
||||
LoginManagerContent._togglePasswordFieldMasking(aEvent.target, unmask);
|
||||
LoginManagerContent.forWindow(window)._togglePasswordFieldMasking(
|
||||
aEvent.target,
|
||||
unmask
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
// Used to watch for changes to fields filled with generated passwords.
|
||||
case "change": {
|
||||
LoginManagerContent._generatedPasswordFilledOrEdited(aEvent.target);
|
||||
LoginManagerContent.forWindow(window)._generatedPasswordFilledOrEdited(
|
||||
aEvent.target
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
// Used to watch for changes to fields filled with generated passwords.
|
||||
case "input": {
|
||||
LoginManagerContent._maybeStopTreatingAsGeneratedPasswordField(aEvent);
|
||||
LoginManagerContent.forWindow(
|
||||
window
|
||||
)._maybeStopTreatingAsGeneratedPasswordField(aEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -226,7 +251,9 @@ const observer = {
|
|||
aEvent.keyCode == aEvent.DOM_VK_TAB ||
|
||||
aEvent.keyCode == aEvent.DOM_VK_RETURN
|
||||
) {
|
||||
LoginManagerContent.onUsernameAutocompleted(aEvent.target);
|
||||
LoginManagerContent.forWindow(window).onUsernameAutocompleted(
|
||||
aEvent.target
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -235,7 +262,7 @@ const observer = {
|
|||
if (aEvent.target.type == "password") {
|
||||
// Used to unmask fields with filled generated passwords when focused.
|
||||
let unmask = true;
|
||||
LoginManagerContent._togglePasswordFieldMasking(
|
||||
LoginManagerContent.forWindow(window)._togglePasswordFieldMasking(
|
||||
aEvent.target,
|
||||
unmask
|
||||
);
|
||||
|
@ -243,7 +270,7 @@ const observer = {
|
|||
}
|
||||
|
||||
// Only used for username fields.
|
||||
LoginManagerContent._onUsernameFocus(aEvent);
|
||||
LoginManagerContent.forWindow(window)._onUsernameFocus(aEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -307,7 +334,7 @@ let gAutoCompleteListener = {
|
|||
return;
|
||||
}
|
||||
|
||||
let focusedElement = LoginManagerContent._formFillService.focusedInput;
|
||||
let focusedElement = gFormFillService.focusedInput;
|
||||
if (
|
||||
event.keyCode != event.DOM_VK_RETURN ||
|
||||
focusedElement != event.target
|
||||
|
@ -319,7 +346,7 @@ let gAutoCompleteListener = {
|
|||
},
|
||||
|
||||
onPopupClosed(selectedRowStyle, mm) {
|
||||
let focusedElement = LoginManagerContent._formFillService.focusedInput;
|
||||
let focusedElement = gFormFillService.focusedInput;
|
||||
let eventTarget = this.keyDownEnterForInput;
|
||||
if (
|
||||
!eventTarget ||
|
||||
|
@ -337,57 +364,58 @@ let gAutoCompleteListener = {
|
|||
},
|
||||
};
|
||||
|
||||
// This object maps to the "child" process (even in the single-process case).
|
||||
this.LoginManagerContent = {
|
||||
__formFillService: null, // FormFillController, for username autocompleting
|
||||
get _formFillService() {
|
||||
if (!this.__formFillService) {
|
||||
this.__formFillService = Cc[
|
||||
"@mozilla.org/satchel/form-fill-controller;1"
|
||||
].getService(Ci.nsIFormFillController);
|
||||
this.LoginManagerContent = class LoginManagerContent {
|
||||
constructor() {
|
||||
/**
|
||||
* WeakMap of the root element of a LoginForm to the DeferredTask to fill its fields.
|
||||
*
|
||||
* This is used to be able to throttle fills for a LoginForm since onDOMInputPasswordAdded gets
|
||||
* dispatched for each password field added to a document but we only want to fill once per
|
||||
* LoginForm when multiple fields are added at once.
|
||||
*
|
||||
* @type {WeakMap}
|
||||
*/
|
||||
this._deferredPasswordAddedTasksByRootElement = new WeakMap();
|
||||
|
||||
/**
|
||||
* WeakMap of a document to the array of callbacks to execute when it becomes visible
|
||||
*
|
||||
* This is used to defer handling DOMFormHasPassword and onDOMInputPasswordAdded events when the
|
||||
* containing document is hidden.
|
||||
* When the document first becomes visible, any queued events will be handled as normal.
|
||||
*
|
||||
* @type {WeakMap}
|
||||
*/
|
||||
this._visibleTasksByDocument = new WeakMap();
|
||||
|
||||
/**
|
||||
* Maps all DOM content documents in this content process, including those in
|
||||
* frames, to the current state used by the Login Manager.
|
||||
*/
|
||||
this._loginFormStateByDocument = new WeakMap();
|
||||
|
||||
// Map from form login requests to information about that request.
|
||||
this._requests = new Map();
|
||||
|
||||
// Number of outstanding requests to each manager.
|
||||
this._managers = new Map();
|
||||
}
|
||||
|
||||
static forWindow(window) {
|
||||
// For now, this is a singleton.
|
||||
if (!gLoginManagerContentSingleton) {
|
||||
gLoginManagerContentSingleton = new LoginManagerContent();
|
||||
}
|
||||
return this.__formFillService;
|
||||
},
|
||||
|
||||
return gLoginManagerContentSingleton;
|
||||
}
|
||||
|
||||
_getRandomId() {
|
||||
return Cc["@mozilla.org/uuid-generator;1"]
|
||||
.getService(Ci.nsIUUIDGenerator)
|
||||
.generateUUID()
|
||||
.toString();
|
||||
},
|
||||
|
||||
_messages: [
|
||||
"PasswordManager:loginsFound",
|
||||
"PasswordManager:loginsAutoCompleted",
|
||||
],
|
||||
|
||||
/**
|
||||
* WeakMap of the root element of a LoginForm to the DeferredTask to fill its fields.
|
||||
*
|
||||
* This is used to be able to throttle fills for a LoginForm since onDOMInputPasswordAdded gets
|
||||
* dispatched for each password field added to a document but we only want to fill once per
|
||||
* LoginForm when multiple fields are added at once.
|
||||
*
|
||||
* @type {WeakMap}
|
||||
*/
|
||||
_deferredPasswordAddedTasksByRootElement: new WeakMap(),
|
||||
|
||||
/**
|
||||
* WeakMap of a document to the array of callbacks to execute when it becomes visible
|
||||
*
|
||||
* This is used to defer handling DOMFormHasPassword and onDOMInputPasswordAdded events when the
|
||||
* containing document is hidden.
|
||||
* When the document first becomes visible, any queued events will be handled as normal.
|
||||
*
|
||||
* @type {WeakMap}
|
||||
*/
|
||||
_onVisibleTasksByDocument: new WeakMap(),
|
||||
|
||||
// Map from form login requests to information about that request.
|
||||
_requests: new Map(),
|
||||
|
||||
// Number of outstanding requests to each manager.
|
||||
_managers: new Map(),
|
||||
}
|
||||
|
||||
_takeRequest(msg) {
|
||||
let data = msg.data;
|
||||
|
@ -399,7 +427,7 @@ this.LoginManagerContent = {
|
|||
if (--count === 0) {
|
||||
this._managers.delete(msg.target);
|
||||
|
||||
for (let message of this._messages) {
|
||||
for (let message of _messages) {
|
||||
msg.target.removeMessageListener(message, this);
|
||||
}
|
||||
} else {
|
||||
|
@ -407,14 +435,14 @@ this.LoginManagerContent = {
|
|||
}
|
||||
|
||||
return request;
|
||||
},
|
||||
}
|
||||
|
||||
_sendRequest(messageManager, requestData, name, messageData) {
|
||||
let count;
|
||||
if (!(count = this._managers.get(messageManager))) {
|
||||
this._managers.set(messageManager, 1);
|
||||
|
||||
for (let message of this._messages) {
|
||||
for (let message of _messages) {
|
||||
messageManager.addMessageListener(message, this);
|
||||
}
|
||||
} else {
|
||||
|
@ -430,7 +458,7 @@ this.LoginManagerContent = {
|
|||
requestData.promise = deferred;
|
||||
this._requests.set(requestId, requestData);
|
||||
return deferred.promise;
|
||||
},
|
||||
}
|
||||
|
||||
_compareAndUpdatePreviouslySentValues(
|
||||
formLikeRoot,
|
||||
|
@ -470,12 +498,12 @@ this.LoginManagerContent = {
|
|||
"_compareAndUpdatePreviouslySentValues: values not equivalent, returning false"
|
||||
);
|
||||
return false;
|
||||
},
|
||||
}
|
||||
|
||||
receiveMessage(msg, topWindow) {
|
||||
receiveMessage(msg) {
|
||||
if (msg.name == "PasswordManager:fillForm") {
|
||||
this.fillForm({
|
||||
topDocument: topWindow.document,
|
||||
topDocument: msg.target.content.document,
|
||||
loginFormOrigin: msg.data.loginFormOrigin,
|
||||
loginsFound: LoginHelper.vanillaObjectsToLogins(msg.data.logins),
|
||||
recipes: msg.data.recipes,
|
||||
|
@ -521,7 +549,7 @@ this.LoginManagerContent = {
|
|||
msg.data.password
|
||||
);
|
||||
this.fillForm({
|
||||
topDocument: topWindow.document,
|
||||
topDocument: msg.target.content.document,
|
||||
loginFormOrigin: msg.data.origin,
|
||||
loginsFound: [generatedLogin],
|
||||
recipes: msg.data.recipes,
|
||||
|
@ -538,7 +566,7 @@ this.LoginManagerContent = {
|
|||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Get relevant logins and recipes from the parent
|
||||
|
@ -572,7 +600,7 @@ this.LoginManagerContent = {
|
|||
"PasswordManager:findLogins",
|
||||
messageData
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
_autoCompleteSearchAsync(aSearchString, aPreviousResult, aElement) {
|
||||
let doc = aElement.ownerDocument;
|
||||
|
@ -614,7 +642,7 @@ this.LoginManagerContent = {
|
|||
"PasswordManager:autoCompleteLogins",
|
||||
messageData
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
setupProgressListener(window) {
|
||||
if (!LoginHelper.formlessCaptureEnabled) {
|
||||
|
@ -633,7 +661,7 @@ this.LoginManagerContent = {
|
|||
} catch (ex) {
|
||||
// Ignore NS_ERROR_FAILURE if the progress listener was already added
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
onDOMFormBeforeSubmit(event) {
|
||||
if (!event.isTrusted) {
|
||||
|
@ -644,15 +672,15 @@ this.LoginManagerContent = {
|
|||
// can grab form data before it might be modified (see bug 257781).
|
||||
log("notified before form submission");
|
||||
let formLike = LoginFormFactory.createFromForm(event.target);
|
||||
LoginManagerContent._onFormSubmit(formLike);
|
||||
},
|
||||
this._onFormSubmit(formLike);
|
||||
}
|
||||
|
||||
onDocumentVisibilityChange(event) {
|
||||
if (!event.isTrusted) {
|
||||
return;
|
||||
}
|
||||
let document = event.target;
|
||||
let onVisibleTasks = this._onVisibleTasksByDocument.get(document);
|
||||
let onVisibleTasks = this._visibleTasksByDocument.get(document);
|
||||
if (!onVisibleTasks) {
|
||||
return;
|
||||
}
|
||||
|
@ -660,8 +688,8 @@ this.LoginManagerContent = {
|
|||
log("onDocumentVisibilityChange, executing queued task");
|
||||
task();
|
||||
}
|
||||
this._onVisibleTasksByDocument.delete(document);
|
||||
},
|
||||
this._visibleTasksByDocument.delete(document);
|
||||
}
|
||||
|
||||
_deferHandlingEventUntilDocumentVisible(event, document, fn) {
|
||||
log(
|
||||
|
@ -669,13 +697,13 @@ this.LoginManagerContent = {
|
|||
event.type
|
||||
}`
|
||||
);
|
||||
let onVisibleTasks = this._onVisibleTasksByDocument.get(document);
|
||||
let onVisibleTasks = this._visibleTasksByDocument.get(document);
|
||||
if (!onVisibleTasks) {
|
||||
log(
|
||||
`deferHandling, first queued event, register the visibilitychange handler`
|
||||
);
|
||||
onVisibleTasks = [];
|
||||
this._onVisibleTasksByDocument.set(document, onVisibleTasks);
|
||||
this._visibleTasksByDocument.set(document, onVisibleTasks);
|
||||
document.addEventListener(
|
||||
"visibilitychange",
|
||||
event => {
|
||||
|
@ -685,7 +713,7 @@ this.LoginManagerContent = {
|
|||
);
|
||||
}
|
||||
onVisibleTasks.push(fn);
|
||||
},
|
||||
}
|
||||
|
||||
onDOMFormHasPassword(event) {
|
||||
if (!event.isTrusted) {
|
||||
|
@ -713,14 +741,14 @@ this.LoginManagerContent = {
|
|||
this._processDOMFormHasPasswordEvent(event);
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_processDOMFormHasPasswordEvent(event) {
|
||||
let form = event.target;
|
||||
let formLike = LoginFormFactory.createFromForm(form);
|
||||
log("_processDOMFormHasPasswordEvent:", form, formLike);
|
||||
this._fetchLoginsFromParentAndFillForm(formLike);
|
||||
},
|
||||
}
|
||||
|
||||
onDOMInputPasswordAdded(event, topWindow) {
|
||||
if (!event.isTrusted) {
|
||||
|
@ -757,7 +785,7 @@ this.LoginManagerContent = {
|
|||
this._processDOMInputPasswordAddedEvent(event, topWindow);
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_processDOMInputPasswordAddedEvent(event, topWindow) {
|
||||
let pwField = event.originalTarget;
|
||||
|
@ -823,7 +851,7 @@ this.LoginManagerContent = {
|
|||
{ once: true }
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch logins from the parent for a given form and then attempt to fill it.
|
||||
|
@ -842,20 +870,14 @@ this.LoginManagerContent = {
|
|||
this._getLoginDataFromParent(form, { showMasterPassword: true })
|
||||
.then(this.loginsFound.bind(this))
|
||||
.catch(Cu.reportError);
|
||||
},
|
||||
|
||||
/**
|
||||
* Maps all DOM content documents in this content process, including those in
|
||||
* frames, to the current state used by the Login Manager.
|
||||
*/
|
||||
loginFormStateByDocument: new WeakMap(),
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a reference to the state object associated with the given
|
||||
* document. This is initialized to an object with default values.
|
||||
*/
|
||||
stateForDocument(document) {
|
||||
let loginFormState = this.loginFormStateByDocument.get(document);
|
||||
let loginFormState = this._loginFormStateByDocument.get(document);
|
||||
if (!loginFormState) {
|
||||
loginFormState = {
|
||||
/**
|
||||
|
@ -868,10 +890,10 @@ this.LoginManagerContent = {
|
|||
lastSubmittedValuesByRootElement: new WeakMap(),
|
||||
loginFormRootElements: new WeakSet(),
|
||||
};
|
||||
this.loginFormStateByDocument.set(document, loginFormState);
|
||||
this._loginFormStateByDocument.set(document, loginFormState);
|
||||
}
|
||||
return loginFormState;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a password fill upon user request coming from the parent process.
|
||||
|
@ -948,7 +970,7 @@ this.LoginManagerContent = {
|
|||
clobberPassword: true,
|
||||
userTriggered: true,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
loginsFound({ form, loginsFound, recipes }) {
|
||||
let doc = form.ownerDocument;
|
||||
|
@ -960,7 +982,7 @@ this.LoginManagerContent = {
|
|||
LoginRecipesContent.cacheRecipes(formOrigin, doc.defaultView, recipes);
|
||||
|
||||
this._fillForm(form, loginsFound, recipes, { autofillForm });
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus event handler for username fields to decide whether to show autocomplete.
|
||||
|
@ -998,8 +1020,8 @@ this.LoginManagerContent = {
|
|||
}
|
||||
|
||||
log("maybeOpenAutocompleteAfterFocus: Opening the autocomplete popup");
|
||||
this._formFillService.showPopup();
|
||||
},
|
||||
gFormFillService.showPopup();
|
||||
}
|
||||
|
||||
/**
|
||||
* A username or password was autocompleted into a field.
|
||||
|
@ -1028,7 +1050,7 @@ this.LoginManagerContent = {
|
|||
this._stopTreatingAsGeneratedPasswordField(acInputField);
|
||||
this._highlightFilledField(acInputField);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* A username field was filled or tabbed away from so try fill in the
|
||||
|
@ -1079,7 +1101,7 @@ this.LoginManagerContent = {
|
|||
} else {
|
||||
// Ignore the event, it's for some input we don't care about.
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {LoginForm} form - the LoginForm to look for password fields in.
|
||||
|
@ -1161,7 +1183,7 @@ this.LoginManagerContent = {
|
|||
}
|
||||
|
||||
return pwFields;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username and password fields found in the form.
|
||||
|
@ -1335,7 +1357,7 @@ this.LoginManagerContent = {
|
|||
log("Password field (old):", oldPasswordField);
|
||||
}
|
||||
return [usernameField, newPasswordField, oldPasswordField];
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the page requests autocomplete be disabled for the
|
||||
|
@ -1343,7 +1365,7 @@ this.LoginManagerContent = {
|
|||
*/
|
||||
_isAutocompleteDisabled(element) {
|
||||
return element && element.autocomplete == "off";
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill a page that was restored from bfcache since we wouldn't receive
|
||||
|
@ -1373,7 +1395,7 @@ this.LoginManagerContent = {
|
|||
let formLike = LoginFormFactory.getForRootElement(formRoot);
|
||||
this._fetchLoginsFromParentAndFillForm(formLike);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger capture on any relevant FormLikes due to a navigation alone (not
|
||||
|
@ -1409,7 +1431,7 @@ this.LoginManagerContent = {
|
|||
let formLike = LoginFormFactory.getForRootElement(formRoot);
|
||||
this._onFormSubmit(formLike);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by our observer when notified of a form submission.
|
||||
|
@ -1548,7 +1570,7 @@ this.LoginManagerContent = {
|
|||
openerTopWindowID,
|
||||
dismissedPrompt,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_maybeStopTreatingAsGeneratedPasswordField(event) {
|
||||
let passwordField = event.target;
|
||||
|
@ -1559,7 +1581,7 @@ this.LoginManagerContent = {
|
|||
if (!value || (event.data && event.data == value)) {
|
||||
this._stopTreatingAsGeneratedPasswordField(passwordField);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_stopTreatingAsGeneratedPasswordField(passwordField) {
|
||||
log("_stopTreatingAsGeneratedPasswordField");
|
||||
|
@ -1574,7 +1596,7 @@ this.LoginManagerContent = {
|
|||
|
||||
// Mask the password field
|
||||
this._togglePasswordFieldMasking(passwordField, false);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the parent that a generated password was filled into a field or
|
||||
|
@ -1652,7 +1674,7 @@ this.LoginManagerContent = {
|
|||
username,
|
||||
}
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
_togglePasswordFieldMasking(passwordField, unmask) {
|
||||
let { editor } = passwordField;
|
||||
|
@ -1677,14 +1699,14 @@ this.LoginManagerContent = {
|
|||
return;
|
||||
}
|
||||
editor.mask();
|
||||
},
|
||||
}
|
||||
|
||||
/** Remove login field highlight when its value is cleared or overwritten.
|
||||
*/
|
||||
_removeFillFieldHighlight(event) {
|
||||
let winUtils = event.target.ownerGlobal.windowUtils;
|
||||
winUtils.removeManuallyManagedState(event.target, AUTOFILL_STATE);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight login fields on autocomplete or autofill on page load.
|
||||
|
@ -1699,7 +1721,7 @@ this.LoginManagerContent = {
|
|||
mozSystemGroup: true,
|
||||
once: true,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter logins for exact origin/formActionOrigin and dedupe on usernamematche
|
||||
|
@ -1746,7 +1768,7 @@ this.LoginManagerContent = {
|
|||
formActionOrigin
|
||||
);
|
||||
return logins;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to find the username and password fields in a form, and fill them
|
||||
|
@ -1871,7 +1893,7 @@ this.LoginManagerContent = {
|
|||
// We would also need this attached to show the insecure login
|
||||
// warning, regardless of saved login.
|
||||
if (usernameField) {
|
||||
this._formFillService.markAsLoginManagerField(usernameField);
|
||||
gFormFillService.markAsLoginManagerField(usernameField);
|
||||
usernameField.addEventListener("keydown", observer);
|
||||
}
|
||||
|
||||
|
@ -2106,7 +2128,7 @@ this.LoginManagerContent = {
|
|||
.add(autofillResult);
|
||||
|
||||
if (usernameField) {
|
||||
let focusedElement = this._formFillService.focusedInput;
|
||||
let focusedElement = gFormFillService.focusedInput;
|
||||
if (
|
||||
usernameField == focusedElement &&
|
||||
autofillResult !== AUTOFILL_RESULT.FILLED
|
||||
|
@ -2114,7 +2136,7 @@ this.LoginManagerContent = {
|
|||
log(
|
||||
"_fillForm: Opening username autocomplete popup since the form wasn't autofilled"
|
||||
);
|
||||
this._formFillService.showPopup();
|
||||
gFormFillService.showPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2130,7 +2152,7 @@ this.LoginManagerContent = {
|
|||
"passwordmgr-processed-form"
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a field, determine whether that field was last filled as a username
|
||||
|
@ -2184,7 +2206,7 @@ this.LoginManagerContent = {
|
|||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username and password fields found in the form by input
|
||||
|
@ -2213,7 +2235,7 @@ this.LoginManagerContent = {
|
|||
let recipes = LoginRecipesContent.getRecipes(formOrigin, doc.defaultView);
|
||||
|
||||
return this._getFormFields(form, false, recipes);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if a field is a valid login form field and
|
||||
|
@ -2261,5 +2283,5 @@ this.LoginManagerContent = {
|
|||
(newPasswordField.disabled || newPasswordField.readOnly),
|
||||
},
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -211,12 +211,14 @@ this.LoginManagerContextMenu = {
|
|||
* origin when subframes are involved.
|
||||
*/
|
||||
_fillTargetField(login, inputElementIdentifier, browser, formOrigin) {
|
||||
LoginManagerParent.fillForm({
|
||||
browser,
|
||||
inputElementIdentifier,
|
||||
loginFormOrigin: formOrigin,
|
||||
login,
|
||||
}).catch(Cu.reportError);
|
||||
LoginManagerParent.getLoginManagerParent()
|
||||
.fillForm({
|
||||
browser,
|
||||
inputElementIdentifier,
|
||||
loginFormOrigin: formOrigin,
|
||||
login,
|
||||
})
|
||||
.catch(Cu.reportError);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,29 +52,46 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
|||
|
||||
const EXPORTED_SYMBOLS = ["LoginManagerParent"];
|
||||
|
||||
this.LoginManagerParent = {
|
||||
/**
|
||||
* A map of a principal's origin (including suffixes) to a generated password string and filled flag
|
||||
* so that we can offer the same password later (e.g. in a confirmation field).
|
||||
*
|
||||
* We don't currently evict from this cache so entries should last until the end of the browser
|
||||
* session. That may change later but for now a typical session would max out at a few entries.
|
||||
*/
|
||||
_generatedPasswordsByPrincipalOrigin: new Map(),
|
||||
let gLoginManagerParentSingleton = null;
|
||||
|
||||
/**
|
||||
* Reference to the default LoginRecipesParent (instead of the initialization promise) for
|
||||
* synchronous access. This is a temporary hack and new consumers should yield on
|
||||
* recipeParentPromise instead.
|
||||
*
|
||||
* @type LoginRecipesParent
|
||||
* @deprecated
|
||||
*/
|
||||
_recipeManager: null,
|
||||
/**
|
||||
* A map of a principal's origin (including suffixes) to a generated password string and filled flag
|
||||
* so that we can offer the same password later (e.g. in a confirmation field).
|
||||
*
|
||||
* We don't currently evict from this cache so entries should last until the end of the browser
|
||||
* session. That may change later but for now a typical session would max out at a few entries.
|
||||
*/
|
||||
let gGeneratedPasswordsByPrincipalOrigin = new Map();
|
||||
|
||||
// Tracks the last time the user cancelled the master password prompt,
|
||||
// to avoid spamming master password prompts on autocomplete searches.
|
||||
_lastMPLoginCancelled: Math.NEGATIVE_INFINITY,
|
||||
/**
|
||||
* Reference to the default LoginRecipesParent (instead of the initialization promise) for
|
||||
* synchronous access. This is a temporary hack and new consumers should yield on
|
||||
* recipeParentPromise instead.
|
||||
*
|
||||
* @type LoginRecipesParent
|
||||
* @deprecated
|
||||
*/
|
||||
let gRecipeManager = null;
|
||||
|
||||
class LoginManagerParent {
|
||||
constructor() {
|
||||
// Tracks the last time the user cancelled the master password prompt,
|
||||
// to avoid spamming master password prompts on autocomplete searches.
|
||||
this._lastMPLoginCancelled = Math.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
// Some unit tests need to access this.
|
||||
static getGeneratedPasswordsByPrincipalOrigin() {
|
||||
return gGeneratedPasswordsByPrincipalOrigin;
|
||||
}
|
||||
|
||||
static getLoginManagerParent() {
|
||||
// For now, this is a singleton.
|
||||
if (!gLoginManagerParentSingleton) {
|
||||
gLoginManagerParentSingleton = new LoginManagerParent();
|
||||
}
|
||||
return gLoginManagerParentSingleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {origin} formOrigin
|
||||
|
@ -134,7 +151,11 @@ this.LoginManagerParent = {
|
|||
formOrigin,
|
||||
formActionOrigin
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
static receiveMessage(msg) {
|
||||
LoginManagerParent.getLoginManagerParent().receiveMessage(msg);
|
||||
}
|
||||
|
||||
// Listeners are added in BrowserGlue.jsm on desktop
|
||||
// and in BrowserCLH.js on mobile.
|
||||
|
@ -155,7 +176,7 @@ this.LoginManagerParent = {
|
|||
|
||||
case "PasswordManager:findRecipes": {
|
||||
let formHost = new URL(data.formOrigin).host;
|
||||
return this._recipeManager.getRecipesForHost(formHost);
|
||||
return gRecipeManager.getRecipesForHost(formHost);
|
||||
}
|
||||
|
||||
case "PasswordManager:onFormSubmit": {
|
||||
|
@ -190,7 +211,7 @@ this.LoginManagerParent = {
|
|||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
}
|
||||
|
||||
// Observers are added in BrowserGlue.jsm on desktop
|
||||
observe(subject, topic, data) {
|
||||
|
@ -199,7 +220,7 @@ this.LoginManagerParent = {
|
|||
(topic == "passwordmgr-storage-changed" && data == "removeLogin")
|
||||
) {
|
||||
let { origin, guid } = subject;
|
||||
let generatedPW = this._generatedPasswordsByPrincipalOrigin.get(origin);
|
||||
let generatedPW = gGeneratedPasswordsByPrincipalOrigin.get(origin);
|
||||
|
||||
// in the case where an autosaved login removed or merged into an existing login,
|
||||
// clear the guid associated with the generated-password cache entry
|
||||
|
@ -215,7 +236,7 @@ this.LoginManagerParent = {
|
|||
generatedPW.storageGUID = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a login form fill and send relevant data (e.g. logins and recipes)
|
||||
|
@ -227,7 +248,7 @@ this.LoginManagerParent = {
|
|||
let formHost;
|
||||
try {
|
||||
formHost = new URL(loginFormOrigin).host;
|
||||
let recipeManager = await this.recipeParentPromise;
|
||||
let recipeManager = await LoginManagerParent.recipeParentPromise;
|
||||
recipes = recipeManager.getRecipesForHost(formHost);
|
||||
} catch (ex) {
|
||||
// Some schemes e.g. chrome aren't supported by URL
|
||||
|
@ -244,7 +265,7 @@ this.LoginManagerParent = {
|
|||
logins: jsLogins,
|
||||
recipes,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Send relevant data (e.g. logins and recipes) to the child process (LoginManagerContent).
|
||||
|
@ -261,7 +282,7 @@ this.LoginManagerParent = {
|
|||
let formHost;
|
||||
try {
|
||||
formHost = new URL(formOrigin).host;
|
||||
let recipeManager = await this.recipeParentPromise;
|
||||
let recipeManager = await LoginManagerParent.recipeParentPromise;
|
||||
recipes = recipeManager.getRecipesForHost(formHost);
|
||||
} catch (ex) {
|
||||
// Some schemes e.g. chrome aren't supported by URL
|
||||
|
@ -351,7 +372,7 @@ this.LoginManagerParent = {
|
|||
logins: jsLogins,
|
||||
recipes,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
doAutocompleteSearch(
|
||||
{
|
||||
|
@ -448,14 +469,14 @@ this.LoginManagerParent = {
|
|||
logins: jsLogins,
|
||||
}
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose `BrowsingContext` so we can stub it in tests.
|
||||
*/
|
||||
get _browsingContextGlobal() {
|
||||
static get _browsingContextGlobal() {
|
||||
return BrowsingContext;
|
||||
},
|
||||
}
|
||||
|
||||
getGeneratedPassword(browsingContextId) {
|
||||
if (
|
||||
|
@ -474,7 +495,7 @@ this.LoginManagerParent = {
|
|||
browsingContext.currentWindowGlobal.documentPrincipal.origin;
|
||||
// Use the same password if we already generated one for this origin so that it doesn't change
|
||||
// with each search/keystroke and the user can easily re-enter a password in a confirmation field.
|
||||
let generatedPW = this._generatedPasswordsByPrincipalOrigin.get(
|
||||
let generatedPW = gGeneratedPasswordsByPrincipalOrigin.get(
|
||||
framePrincipalOrigin
|
||||
);
|
||||
if (generatedPW) {
|
||||
|
@ -493,12 +514,9 @@ this.LoginManagerParent = {
|
|||
storageGUID: null,
|
||||
value: PasswordGenerator.generatePassword(),
|
||||
};
|
||||
this._generatedPasswordsByPrincipalOrigin.set(
|
||||
framePrincipalOrigin,
|
||||
generatedPW
|
||||
);
|
||||
gGeneratedPasswordsByPrincipalOrigin.set(framePrincipalOrigin, generatedPW);
|
||||
return generatedPW.value;
|
||||
},
|
||||
}
|
||||
|
||||
_getPrompter(browser, openerTopWindowID) {
|
||||
let prompterSvc = Cc[
|
||||
|
@ -519,7 +537,7 @@ this.LoginManagerParent = {
|
|||
}
|
||||
|
||||
return prompterSvc;
|
||||
},
|
||||
}
|
||||
|
||||
onFormSubmit(
|
||||
browser,
|
||||
|
@ -585,7 +603,7 @@ this.LoginManagerParent = {
|
|||
formActionOrigin,
|
||||
});
|
||||
|
||||
let generatedPW = this._generatedPasswordsByPrincipalOrigin.get(origin);
|
||||
let generatedPW = gGeneratedPasswordsByPrincipalOrigin.get(origin);
|
||||
let autoSavedStorageGUID = "";
|
||||
if (generatedPW && generatedPW.storageGUID) {
|
||||
autoSavedStorageGUID = generatedPW.storageGUID;
|
||||
|
@ -700,7 +718,7 @@ this.LoginManagerParent = {
|
|||
// Prompt user to save login (via dialog or notification bar)
|
||||
let prompter = this._getPrompter(browser, openerTopWindowID);
|
||||
prompter.promptToSavePassword(formLogin, dismissedPrompt);
|
||||
},
|
||||
}
|
||||
|
||||
_onGeneratedPasswordFilledOrEdited({
|
||||
browsingContextId,
|
||||
|
@ -742,7 +760,7 @@ this.LoginManagerParent = {
|
|||
|
||||
let framePrincipalOrigin =
|
||||
browsingContext.currentWindowGlobal.documentPrincipal.origin;
|
||||
let generatedPW = this._generatedPasswordsByPrincipalOrigin.get(
|
||||
let generatedPW = gGeneratedPasswordsByPrincipalOrigin.get(
|
||||
framePrincipalOrigin
|
||||
);
|
||||
|
||||
|
@ -916,22 +934,21 @@ this.LoginManagerParent = {
|
|||
true, // dismissed prompt
|
||||
shouldAutoSaveLogin // notifySaved
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
XPCOMUtils.defineLazyGetter(
|
||||
LoginManagerParent,
|
||||
"recipeParentPromise",
|
||||
function() {
|
||||
const { LoginRecipesParent } = ChromeUtils.import(
|
||||
"resource://gre/modules/LoginRecipes.jsm"
|
||||
);
|
||||
this._recipeManager = new LoginRecipesParent({
|
||||
defaults: Services.prefs.getStringPref("signon.recipes.path"),
|
||||
});
|
||||
return this._recipeManager.initializationPromise;
|
||||
}
|
||||
);
|
||||
|
||||
static get recipeParentPromise() {
|
||||
if (!gRecipeManager) {
|
||||
const { LoginRecipesParent } = ChromeUtils.import(
|
||||
"resource://gre/modules/LoginRecipes.jsm"
|
||||
);
|
||||
gRecipeManager = new LoginRecipesParent({
|
||||
defaults: Services.prefs.getStringPref("signon.recipes.path"),
|
||||
});
|
||||
}
|
||||
|
||||
return gRecipeManager.initializationPromise;
|
||||
}
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
LoginManagerParent,
|
||||
|
|
|
@ -78,7 +78,7 @@ this.LoginTestUtils = {
|
|||
let { LoginManagerParent } = ChromeUtils.import(
|
||||
"resource://gre/modules/LoginManagerParent.jsm"
|
||||
);
|
||||
LoginManagerParent._generatedPasswordsByPrincipalOrigin.clear();
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().clear();
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -75,12 +75,17 @@ add_task(async function test() {
|
|||
let formLike = LoginFormFactory.createFromField(password);
|
||||
info("Calling _fillForm with FormLike");
|
||||
addedLogin = LoginHelper.vanillaObjectToLogin(addedLogin);
|
||||
LoginManagerContent._fillForm(formLike, [addedLogin], null, {
|
||||
autofillForm: true,
|
||||
clobberUsername: true,
|
||||
clobberPassword: true,
|
||||
userTriggered: true,
|
||||
});
|
||||
LoginManagerContent.forWindow(content)._fillForm(
|
||||
formLike,
|
||||
[addedLogin],
|
||||
null,
|
||||
{
|
||||
autofillForm: true,
|
||||
clobberUsername: true,
|
||||
clobberPassword: true,
|
||||
userTriggered: true,
|
||||
}
|
||||
);
|
||||
|
||||
if (aUsernameRequested) {
|
||||
let username = content.document.querySelector("#form-basic-username");
|
||||
|
|
|
@ -752,7 +752,7 @@ add_task(async function autocomplete_generated_password_edited_no_auto_save() {
|
|||
}
|
||||
);
|
||||
|
||||
LMP._generatedPasswordsByPrincipalOrigin.clear();
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().clear();
|
||||
});
|
||||
|
||||
add_task(async function contextmenu_fill_generated_password_and_set_username() {
|
||||
|
@ -1029,7 +1029,7 @@ add_task(
|
|||
info("autoSavedLogin, guid: " + autoSavedLogin.guid);
|
||||
|
||||
info("verifyLogins ok");
|
||||
let passwordCacheEntry = LoginManagerParent._generatedPasswordsByPrincipalOrigin.get(
|
||||
let passwordCacheEntry = LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://example.com"
|
||||
);
|
||||
|
||||
|
@ -1124,7 +1124,7 @@ add_task(
|
|||
// make sure the cache entry is unchanged with the removal of the auto-saved login
|
||||
is(
|
||||
autoSavedLogin.password,
|
||||
LoginManagerParent._generatedPasswordsByPrincipalOrigin.get(
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://example.com"
|
||||
).value,
|
||||
"Generated password cache entry has the expected password value"
|
||||
|
@ -1200,7 +1200,7 @@ add_task(async function autosaved_login_updated_to_existing_login_onsubmit() {
|
|||
info("autoSavedLogin, guid: " + autoSavedLogin.guid);
|
||||
|
||||
info("verifyLogins ok");
|
||||
let passwordCacheEntry = LoginManagerParent._generatedPasswordsByPrincipalOrigin.get(
|
||||
let passwordCacheEntry = LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://example.com"
|
||||
);
|
||||
|
||||
|
@ -1319,7 +1319,7 @@ add_task(async function autosaved_login_updated_to_existing_login_onsubmit() {
|
|||
// make sure the cache entry is unchanged with the removal of the auto-saved login
|
||||
is(
|
||||
autoSavedLogin.password,
|
||||
LoginManagerParent._generatedPasswordsByPrincipalOrigin.get(
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://example.com"
|
||||
).value,
|
||||
"Generated password cache entry has the expected password value"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const DIRECTORY_PATH = "/browser/toolkit/components/passwordmgr/test/browser/";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/LoginHelper.jsm", this);
|
||||
const { LoginManagerParent: LMP } = ChromeUtils.import(
|
||||
const { LoginManagerParent } = ChromeUtils.import(
|
||||
"resource://gre/modules/LoginManagerParent.jsm"
|
||||
);
|
||||
ChromeUtils.import("resource://testing-common/LoginTestUtils.jsm", this);
|
||||
|
|
|
@ -62,7 +62,7 @@ add_task(async function test_preventDefaultAndStopPropagation() {
|
|||
|
||||
SpecialPowers.wrap(pword).setUserInput("generatedpass");
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, true, "Before first fill");
|
||||
LoginManagerContent._generatedPasswordFilledOrEdited(pword);
|
||||
LoginManagerContent.forWindow(window)._generatedPasswordFilledOrEdited(pword);
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, false, "After first fill");
|
||||
synthesizeKey("KEY_Tab"); // blur
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, true, "After blur");
|
||||
|
@ -80,7 +80,7 @@ add_task(async function test_fieldsMaskedAfterSavedLoginFill() {
|
|||
|
||||
SpecialPowers.wrap(pword).setUserInput("generatedpass");
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, true, "Before first fill");
|
||||
LoginManagerContent._generatedPasswordFilledOrEdited(pword);
|
||||
LoginManagerContent.forWindow(window)._generatedPasswordFilledOrEdited(pword);
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, false, "After first fill");
|
||||
synthesizeKey("KEY_Tab", { shiftKey: true }); // blur pw, focus un
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, true, "After blur");
|
||||
|
@ -105,7 +105,7 @@ add_task(async function test_fieldsMaskedAfterReplacingWholeValue() {
|
|||
|
||||
SpecialPowers.wrap(pword).setUserInput("generatedpass");
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, true, "Before first fill");
|
||||
LoginManagerContent._generatedPasswordFilledOrEdited(pword);
|
||||
LoginManagerContent.forWindow(window)._generatedPasswordFilledOrEdited(pword);
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, false, "After first fill");
|
||||
synthesizeKey("KEY_Tab", { shiftKey: true }); // blur pw, focus un
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, true, "After blur");
|
||||
|
@ -132,7 +132,7 @@ add_task(async function test_fieldsUnmaskedAfterAddingCharacter() {
|
|||
|
||||
SpecialPowers.wrap(pword).setUserInput("generatedpass");
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, true, "Before first fill");
|
||||
LoginManagerContent._generatedPasswordFilledOrEdited(pword);
|
||||
LoginManagerContent.forWindow(window)._generatedPasswordFilledOrEdited(pword);
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, false, "After first fill");
|
||||
synthesizeKey("KEY_Tab", { shiftKey: true }); // blur pw, focus un
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, true, "After blur");
|
||||
|
@ -160,7 +160,7 @@ add_task(async function test_typeNotPassword() {
|
|||
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, true, "Before first fill");
|
||||
SpecialPowers.wrap(pword).setUserInput("generatedpass");
|
||||
LoginManagerContent._generatedPasswordFilledOrEdited(pword);
|
||||
LoginManagerContent.forWindow(window)._generatedPasswordFilledOrEdited(pword);
|
||||
LOGIN_FIELD_UTILS.checkPasswordMasked(pword, false, "After first fill");
|
||||
|
||||
// Simulate a website doing their own unmasking and re-masking
|
||||
|
|
|
@ -21,8 +21,8 @@ function initLogins() {
|
|||
|
||||
const {LoginManagerParent} = ChromeUtils.import("resource://gre/modules/LoginManagerParent.jsm");
|
||||
Services.telemetry.clearEvents();
|
||||
if (LoginManagerParent._generatedPasswordsByPrincipalOrigin) {
|
||||
LoginManagerParent._generatedPasswordsByPrincipalOrigin.clear();
|
||||
if (LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin()) {
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().clear();
|
||||
}
|
||||
Services.logins.addLogin(login1);
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ add_task(async function test() {
|
|||
|
||||
info("Calling _onFormSubmit with FormLike");
|
||||
let processedPromise = getSubmitMessage();
|
||||
LoginManagerContent._onFormSubmit(formLike);
|
||||
LoginManagerContent.forWindow(frameDoc.defaultView)._onFormSubmit(formLike);
|
||||
|
||||
let submittedResult = await processedPromise;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"use strict";
|
||||
|
||||
const { sinon } = ChromeUtils.import("resource://testing-common/Sinon.jsm");
|
||||
const { LoginManagerParent: LMP } = ChromeUtils.import(
|
||||
const { LoginManagerParent } = ChromeUtils.import(
|
||||
"resource://gre/modules/LoginManagerParent.jsm"
|
||||
);
|
||||
|
||||
|
@ -13,6 +13,8 @@ add_task(async function test_doAutocompleteSearch_generated_noLogins() {
|
|||
Services.prefs.setBoolPref("signon.generation.available", true); // TODO: test both with false
|
||||
Services.prefs.setBoolPref("signon.generation.enabled", true);
|
||||
|
||||
let LMP = new LoginManagerParent();
|
||||
|
||||
ok(LMP.doAutocompleteSearch, "doAutocompleteSearch exists");
|
||||
|
||||
// Default to the happy path
|
||||
|
@ -50,7 +52,7 @@ add_task(async function test_doAutocompleteSearch_generated_noLogins() {
|
|||
};
|
||||
|
||||
sinon
|
||||
.stub(LMP._browsingContextGlobal, "get")
|
||||
.stub(LoginManagerParent._browsingContextGlobal, "get")
|
||||
.withArgs(123)
|
||||
.callsFake(() => {
|
||||
return {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"use strict";
|
||||
|
||||
const { sinon } = ChromeUtils.import("resource://testing-common/Sinon.jsm");
|
||||
const { LoginManagerParent: LMP } = ChromeUtils.import(
|
||||
const { LoginManagerParent } = ChromeUtils.import(
|
||||
"resource://gre/modules/LoginManagerParent.jsm"
|
||||
);
|
||||
|
||||
|
@ -14,23 +14,28 @@ add_task(async function test_getGeneratedPassword() {
|
|||
Services.prefs.setBoolPref("signon.generation.available", true);
|
||||
Services.prefs.setBoolPref("signon.generation.enabled", true);
|
||||
|
||||
let LMP = new LoginManagerParent();
|
||||
|
||||
ok(LMP.getGeneratedPassword, "LMP.getGeneratedPassword exists");
|
||||
equal(
|
||||
LMP._generatedPasswordsByPrincipalOrigin.size,
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().size,
|
||||
0,
|
||||
"Empty cache to start"
|
||||
);
|
||||
|
||||
equal(LMP.getGeneratedPassword(99), null, "Null with no BrowsingContext");
|
||||
|
||||
ok(LMP._browsingContextGlobal, "Check _browsingContextGlobal exists");
|
||||
ok(
|
||||
!LMP._browsingContextGlobal.get(99),
|
||||
LoginManagerParent._browsingContextGlobal,
|
||||
"Check _browsingContextGlobal exists"
|
||||
);
|
||||
ok(
|
||||
!LoginManagerParent._browsingContextGlobal.get(99),
|
||||
"BrowsingContext 99 shouldn't exist yet"
|
||||
);
|
||||
info("Stubbing BrowsingContext.get(99)");
|
||||
sinon
|
||||
.stub(LMP._browsingContextGlobal, "get")
|
||||
.stub(LoginManagerParent._browsingContextGlobal, "get")
|
||||
.withArgs(99)
|
||||
.callsFake(() => {
|
||||
return {
|
||||
|
@ -42,7 +47,7 @@ add_task(async function test_getGeneratedPassword() {
|
|||
};
|
||||
});
|
||||
ok(
|
||||
LMP._browsingContextGlobal.get(99),
|
||||
LoginManagerParent._browsingContextGlobal.get(99),
|
||||
"Checking BrowsingContext.get(99) stub"
|
||||
);
|
||||
|
||||
|
@ -53,9 +58,13 @@ add_task(async function test_getGeneratedPassword() {
|
|||
LoginTestUtils.generation.LENGTH,
|
||||
"Check password length"
|
||||
);
|
||||
equal(LMP._generatedPasswordsByPrincipalOrigin.size, 1, "1 added to cache");
|
||||
equal(
|
||||
LMP._generatedPasswordsByPrincipalOrigin.get(
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().size,
|
||||
1,
|
||||
"1 added to cache"
|
||||
);
|
||||
equal(
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://www.example.com^userContextId=6"
|
||||
).value,
|
||||
password1,
|
||||
|
@ -69,9 +78,9 @@ add_task(async function test_getGeneratedPassword() {
|
|||
);
|
||||
|
||||
info("Changing the documentPrincipal to simulate a navigation in the frame");
|
||||
LMP._browsingContextGlobal.get.restore();
|
||||
LoginManagerParent._browsingContextGlobal.get.restore();
|
||||
sinon
|
||||
.stub(LMP._browsingContextGlobal, "get")
|
||||
.stub(LoginManagerParent._browsingContextGlobal, "get")
|
||||
.withArgs(99)
|
||||
.callsFake(() => {
|
||||
return {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"use strict";
|
||||
|
||||
const { sinon } = ChromeUtils.import("resource://testing-common/Sinon.jsm");
|
||||
const { LoginManagerParent: LMP } = ChromeUtils.import(
|
||||
const { LoginManagerParent } = ChromeUtils.import(
|
||||
"resource://gre/modules/LoginManagerParent.jsm"
|
||||
);
|
||||
const { LoginManagerPrompter } = ChromeUtils.import(
|
||||
|
@ -19,6 +19,8 @@ const loginTemplate = Object.freeze({
|
|||
formActionOrigin: "https://www.mozilla.org",
|
||||
});
|
||||
|
||||
let LMP = new LoginManagerParent();
|
||||
|
||||
function stubPrompter() {
|
||||
let fakePromptToSavePassword = sinon.stub();
|
||||
let fakePromptToChangePassword = sinon.stub();
|
||||
|
@ -57,14 +59,17 @@ function stubPrompter() {
|
|||
}
|
||||
|
||||
function stubGeneratedPasswordForBrowsingContextId(id) {
|
||||
ok(LMP._browsingContextGlobal, "Check _browsingContextGlobal exists");
|
||||
ok(
|
||||
!LMP._browsingContextGlobal.get(id),
|
||||
LoginManagerParent._browsingContextGlobal,
|
||||
"Check _browsingContextGlobal exists"
|
||||
);
|
||||
ok(
|
||||
!LoginManagerParent._browsingContextGlobal.get(id),
|
||||
`BrowsingContext ${id} shouldn't exist yet`
|
||||
);
|
||||
info(`Stubbing BrowsingContext.get(${id})`);
|
||||
let stub = sinon
|
||||
.stub(LMP._browsingContextGlobal, "get")
|
||||
.stub(LoginManagerParent._browsingContextGlobal, "get")
|
||||
.withArgs(id)
|
||||
.callsFake(() => {
|
||||
return {
|
||||
|
@ -79,7 +84,7 @@ function stubGeneratedPasswordForBrowsingContextId(id) {
|
|||
};
|
||||
});
|
||||
ok(
|
||||
LMP._browsingContextGlobal.get(id),
|
||||
LoginManagerParent._browsingContextGlobal.get(id),
|
||||
`Checking BrowsingContext.get(${id}) stub`
|
||||
);
|
||||
|
||||
|
@ -90,15 +95,19 @@ function stubGeneratedPasswordForBrowsingContextId(id) {
|
|||
LoginTestUtils.generation.LENGTH,
|
||||
"Check password length"
|
||||
);
|
||||
equal(LMP._generatedPasswordsByPrincipalOrigin.size, 1, "1 added to cache");
|
||||
equal(
|
||||
LMP._generatedPasswordsByPrincipalOrigin.get(
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().size,
|
||||
1,
|
||||
"1 added to cache"
|
||||
);
|
||||
equal(
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://www.example.com^userContextId=6"
|
||||
).value,
|
||||
generatedPassword,
|
||||
"Cache key and value"
|
||||
);
|
||||
LMP._browsingContextGlobal.get.resetHistory();
|
||||
LoginManagerParent._browsingContextGlobal.get.resetHistory();
|
||||
|
||||
return {
|
||||
stub,
|
||||
|
@ -148,7 +157,7 @@ function startTestConditions(contextId) {
|
|||
"Null with no BrowsingContext"
|
||||
);
|
||||
equal(
|
||||
LMP._generatedPasswordsByPrincipalOrigin.size,
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().size,
|
||||
0,
|
||||
"Empty cache to start"
|
||||
);
|
||||
|
@ -242,7 +251,7 @@ add_task(async function test_onGeneratedPasswordFilledOrEdited() {
|
|||
username: "someusername",
|
||||
password: newPassword,
|
||||
});
|
||||
let generatedPW = LMP._generatedPasswordsByPrincipalOrigin.get(
|
||||
let generatedPW = LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://www.example.com^userContextId=6"
|
||||
);
|
||||
ok(generatedPW.edited, "Cached edited boolean should be true");
|
||||
|
@ -271,7 +280,7 @@ add_task(async function test_onGeneratedPasswordFilledOrEdited() {
|
|||
username: "someusername",
|
||||
password: newerPassword,
|
||||
});
|
||||
generatedPW = LMP._generatedPasswordsByPrincipalOrigin.get(
|
||||
generatedPW = LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://www.example.com^userContextId=6"
|
||||
);
|
||||
ok(generatedPW.edited, "Cached edited state should remain true");
|
||||
|
@ -288,9 +297,9 @@ add_task(async function test_onGeneratedPasswordFilledOrEdited() {
|
|||
|
||||
checkEditTelemetryRecorded(1, "with auto-save");
|
||||
|
||||
LMP._browsingContextGlobal.get.restore();
|
||||
LoginManagerParent._browsingContextGlobal.get.restore();
|
||||
restorePrompter();
|
||||
LMP._generatedPasswordsByPrincipalOrigin.clear();
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().clear();
|
||||
Services.logins.removeAllLogins();
|
||||
Services.telemetry.clearEvents();
|
||||
});
|
||||
|
@ -350,7 +359,7 @@ add_task(async function test_onGeneratedPasswordFilledOrEdited_editToEmpty() {
|
|||
username: "someusername",
|
||||
password: newPassword,
|
||||
});
|
||||
let generatedPW = LMP._generatedPasswordsByPrincipalOrigin.get(
|
||||
let generatedPW = LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://www.example.com^userContextId=6"
|
||||
);
|
||||
ok(!generatedPW.edited, "Cached edited boolean should be false");
|
||||
|
@ -362,9 +371,9 @@ add_task(async function test_onGeneratedPasswordFilledOrEdited_editToEmpty() {
|
|||
|
||||
checkEditTelemetryRecorded(0, "Blanking doesn't count as an edit");
|
||||
|
||||
LMP._browsingContextGlobal.get.restore();
|
||||
LoginManagerParent._browsingContextGlobal.get.restore();
|
||||
restorePrompter();
|
||||
LMP._generatedPasswordsByPrincipalOrigin.clear();
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().clear();
|
||||
Services.logins.removeAllLogins();
|
||||
Services.telemetry.clearEvents();
|
||||
});
|
||||
|
@ -433,7 +442,7 @@ add_task(async function test_addUsernameBeforeAutoSaveEdit() {
|
|||
username: "someusername",
|
||||
password: newPassword,
|
||||
});
|
||||
let generatedPW = LMP._generatedPasswordsByPrincipalOrigin.get(
|
||||
let generatedPW = LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://www.example.com^userContextId=6"
|
||||
);
|
||||
ok(generatedPW.edited, "Cached edited boolean should be true");
|
||||
|
@ -463,7 +472,7 @@ add_task(async function test_addUsernameBeforeAutoSaveEdit() {
|
|||
username: "someusername",
|
||||
password: newerPassword,
|
||||
});
|
||||
generatedPW = LMP._generatedPasswordsByPrincipalOrigin.get(
|
||||
generatedPW = LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://www.example.com^userContextId=6"
|
||||
);
|
||||
ok(generatedPW.edited, "Cached edited state should remain true");
|
||||
|
@ -481,9 +490,9 @@ add_task(async function test_addUsernameBeforeAutoSaveEdit() {
|
|||
|
||||
checkEditTelemetryRecorded(1, "with auto-save");
|
||||
|
||||
LMP._browsingContextGlobal.get.restore();
|
||||
LoginManagerParent._browsingContextGlobal.get.restore();
|
||||
restorePrompter();
|
||||
LMP._generatedPasswordsByPrincipalOrigin.clear();
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().clear();
|
||||
Services.logins.removeAllLogins();
|
||||
Services.telemetry.clearEvents();
|
||||
});
|
||||
|
@ -509,9 +518,9 @@ add_task(
|
|||
ok(LMP._getPrompter.notCalled, "Checking _getPrompter wasn't called");
|
||||
|
||||
// Clean up
|
||||
LMP._browsingContextGlobal.get.restore();
|
||||
LoginManagerParent._browsingContextGlobal.get.restore();
|
||||
restorePrompter();
|
||||
LMP._generatedPasswordsByPrincipalOrigin.clear();
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().clear();
|
||||
Services.logins.setLoginSavingEnabled("https://www.example.com", true);
|
||||
Services.logins.removeAllLogins();
|
||||
}
|
||||
|
@ -571,7 +580,7 @@ add_task(
|
|||
username: "someusername",
|
||||
password: newPassword,
|
||||
});
|
||||
let generatedPW = LMP._generatedPasswordsByPrincipalOrigin.get(
|
||||
let generatedPW = LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://www.example.com^userContextId=6"
|
||||
);
|
||||
ok(generatedPW.edited, "Cached edited boolean should be true");
|
||||
|
@ -587,9 +596,9 @@ add_task(
|
|||
|
||||
checkEditTelemetryRecorded(1, "Updating cache, not storage (no auto-save)");
|
||||
|
||||
LMP._browsingContextGlobal.get.restore();
|
||||
LoginManagerParent._browsingContextGlobal.get.restore();
|
||||
restorePrompter();
|
||||
LMP._generatedPasswordsByPrincipalOrigin.clear();
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().clear();
|
||||
Services.logins.removeAllLogins();
|
||||
Services.telemetry.clearEvents();
|
||||
}
|
||||
|
@ -598,7 +607,7 @@ add_task(
|
|||
add_task(
|
||||
async function test_onGeneratedPasswordFilledOrEdited_withSavedEmptyUsernameAndUsernameValue() {
|
||||
// Save as the above task but with a non-empty username field value.
|
||||
startTestConditions();
|
||||
startTestConditions(99);
|
||||
let login0Props = Object.assign({}, loginTemplate, {
|
||||
username: "",
|
||||
password: "qweqweq",
|
||||
|
@ -676,7 +685,7 @@ add_task(
|
|||
"promptToSavePassword had a falsey 'notifySaved' argument"
|
||||
);
|
||||
|
||||
let generatedPW = LMP._generatedPasswordsByPrincipalOrigin.get(
|
||||
let generatedPW = LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().get(
|
||||
"https://www.example.com^userContextId=6"
|
||||
);
|
||||
ok(generatedPW.edited, "Cached edited boolean should be true");
|
||||
|
@ -695,9 +704,9 @@ add_task(
|
|||
"Updating cache, not storage (no auto-save) with username in field"
|
||||
);
|
||||
|
||||
LMP._browsingContextGlobal.get.restore();
|
||||
LoginManagerParent._browsingContextGlobal.get.restore();
|
||||
restorePrompter();
|
||||
LMP._generatedPasswordsByPrincipalOrigin.clear();
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().clear();
|
||||
Services.logins.removeAllLogins();
|
||||
Services.telemetry.clearEvents();
|
||||
}
|
||||
|
@ -754,9 +763,9 @@ add_task(
|
|||
"promptToChangePassword had a truthy 'notifySaved' argument"
|
||||
);
|
||||
|
||||
LMP._browsingContextGlobal.get.restore();
|
||||
LoginManagerParent._browsingContextGlobal.get.restore();
|
||||
restorePrompter();
|
||||
LMP._generatedPasswordsByPrincipalOrigin.clear();
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().clear();
|
||||
Services.logins.removeAllLogins();
|
||||
}
|
||||
);
|
||||
|
@ -810,9 +819,9 @@ add_task(
|
|||
"promptToChangePassword had a truthy 'notifySaved' argument"
|
||||
);
|
||||
|
||||
LMP._browsingContextGlobal.get.restore();
|
||||
LoginManagerParent._browsingContextGlobal.get.restore();
|
||||
restorePrompter();
|
||||
LMP._generatedPasswordsByPrincipalOrigin.clear();
|
||||
LoginManagerParent.getGeneratedPasswordsByPrincipalOrigin().clear();
|
||||
Services.logins.removeAllLogins();
|
||||
}
|
||||
);
|
||||
|
|
|
@ -167,7 +167,7 @@ add_task(async function test_searchAndDedupeLogins_acceptDifferentSubdomains() {
|
|||
"Check length of added logins"
|
||||
);
|
||||
|
||||
let actual = LMP._searchAndDedupeLogins(tc.formActionOrigin, {
|
||||
let actual = new LMP()._searchAndDedupeLogins(tc.formActionOrigin, {
|
||||
formActionOrigin: tc.formActionOrigin,
|
||||
looseActionOriginMatch: true,
|
||||
acceptDifferentSubdomains: true,
|
||||
|
|
|
@ -161,7 +161,7 @@ for (let tc of TESTCASES) {
|
|||
await testcase.beforeGetFunction(document, formLike);
|
||||
}
|
||||
|
||||
let actual = LoginManagerContent._getFormFields(
|
||||
let actual = new LoginManagerContent()._getFormFields(
|
||||
formLike,
|
||||
testcase.skipEmptyFields,
|
||||
new Set()
|
||||
|
|
|
@ -197,7 +197,7 @@ for (let tc of TESTCASES) {
|
|||
let formLikeIndex = -1;
|
||||
for (let formLikeFromInput of mapRootElementToFormLike.values()) {
|
||||
formLikeIndex++;
|
||||
let pwFields = LoginManagerContent._getPasswordFields(
|
||||
let pwFields = new LoginManagerContent()._getPasswordFields(
|
||||
formLikeFromInput,
|
||||
{
|
||||
fieldOverrideRecipe: testcase.fieldOverrideRecipe,
|
||||
|
@ -287,7 +287,7 @@ for (let tc of EMOJI_TESTCASES) {
|
|||
let input = document.querySelector("input[type='password']");
|
||||
Assert.ok(input, "Found the password field");
|
||||
let formLike = LoginFormFactory.createFromField(input);
|
||||
let pwFields = LoginManagerContent._getPasswordFields(formLike, {
|
||||
let pwFields = new LoginManagerContent()._getPasswordFields(formLike, {
|
||||
minPasswordLength: testcase.minPasswordLength,
|
||||
});
|
||||
info("Got password fields: " + pwFields.length);
|
||||
|
|
|
@ -111,7 +111,9 @@ for (let tc of TESTCASES) {
|
|||
let formOrigin = LoginHelper.getLoginOrigin(document.documentURI);
|
||||
LoginRecipesContent.cacheRecipes(formOrigin, win, new Set());
|
||||
|
||||
let actual = LoginManagerContent.getUserNameAndPasswordFields(input);
|
||||
let actual = new LoginManagerContent().getUserNameAndPasswordFields(
|
||||
input
|
||||
);
|
||||
|
||||
Assert.strictEqual(
|
||||
testcase.returnedFieldIDs.length,
|
||||
|
|
Загрузка…
Ссылка в новой задаче