Bug 1370391 - integrate heuristics into results. r=mattn
MozReview-Commit-ID: Jy7mKOz2Hce
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -92,17 +92,18 @@ AutofillProfileAutoCompleteSearch.protot
this.log.debug("startSearch: for", searchString, "with input", formFillController.focusedInput);
let focusedInput = formFillController.focusedInput;
this.forceStop = false;
let info = FormAutofillContent.getInputDetails(focusedInput);
if (!FormAutofillContent.savedFieldNames.has(info.fieldName) ||
FormAutofillContent.getFormHandler(focusedInput).filledProfileGUID) {
let formHistory = Cc["@mozilla.org/autocomplete/search;1?name=form-history"]
- .createInstance(Ci.nsIAutoCompleteSearch);
+ .getService(Ci.nsIAutoCompleteSearch);
+
formHistory.startSearch(searchString, searchParam, previousResult, {
onSearchResult: (search, result) => {
listener.onSearchResult(this, result);
ProfileAutocomplete.setProfileAutoCompleteResult(result);
},
});
return;
}
@@ -399,16 +400,20 @@ var FormAutofillContent = {
*
* @param {HTMLInputElement} element Focused input which triggered profile searching
* @returns {Object|null}
* Return target input's information that cloned from content cache
* (or return null if the information is not found in the cache).
*/
getInputDetails(element) {
let formDetails = this.getFormDetails(element);
+ if (!formDetails) {
+ return null;
+ }
+
for (let detail of formDetails) {
let detailElement = detail.elementWeakRef.get();
if (detailElement && element == detailElement) {
return detail;
}
}
return null;
},
--- a/toolkit/components/satchel/FormHistoryStartup.js
+++ b/toolkit/components/satchel/FormHistoryStartup.js
@@ -127,19 +127,25 @@ FormHistoryStartup.prototype = {
// query might have been canceled shortly before completing, in
// that case we don't want to call the callback anymore.
if (query === this.pendingQuery) {
this.pendingQuery = null;
if (aReason) {
return;
}
- // for now we only query autofill storage for @type=email
- if (params.fieldtype == "email") {
- let autofillValues = this.getAutofillValues("email", searchString);
+ // for now we only query autofill storage for type=email
+ const ALLOWED_FIELDTYPES = ["email"];
+ let index = ALLOWED_FIELDTYPES.indexOf(params.heuristicsFieldType);
+ if (index == -1) { // heuristics fieldType is not good, try the input type itself
+ index = ALLOWED_FIELDTYPES.indexOf(params.fieldtype);
+ }
+ if (index != -1) { // one of heuristics or input type works, use it w/ autofill
+ const fieldType = ALLOWED_FIELDTYPES[index];
+ let autofillValues = this.getAutofillValues(fieldType, searchString);
results = this.dedupeAutofillAndHistory(autofillValues, results);
}
// compute frecency and remove metadata of deduped results
for (let result of results) {
result.frecency = FormHistory.computeFrecency(params, result.metadata);
delete result.metadata;
}
--- a/toolkit/components/satchel/nsFormAutoComplete.js
+++ b/toolkit/components/satchel/nsFormAutoComplete.js
@@ -6,16 +6,30 @@
"use strict";
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils", "resource://gre/modules/BrowserUtils.jsm");
+// Gracefully handle if the Form Autofill System Add-on isn't installed in this locale or for this user.
+// defineLazyModuleGetter would report to the console.
+XPCOMUtils.defineLazyGetter(this, "FormAutofillContent", () => {
+ let _formAutofillContent;
+
+ try {
+ _formAutofillContent = Cu.import("resource://formautofill/FormAutofillContent.jsm", {})
+ .FormAutofillContent;
+ } catch (e) {
+ _formAutofillContent = null;
+ }
+
+ return _formAutofillContent;
+});
function isAutocompleteDisabled(aField) {
if (aField.autocomplete !== "") {
return aField.autocomplete === "off";
}
return aField.form && aField.form.autocomplete === "off";
}
@@ -500,26 +514,30 @@ FormAutoComplete.prototype = {
* @param {string} searchString
* string to search for
* @param {function} callback
* called when the values are available. Passed an array of objects,
* containing properties for each result. The callback is only called
* when successful.
*/
getAutoCompleteValues(client, field, inputName, searchString, callback) {
+ let heuristics = field && FormAutofillContent ?
+ FormAutofillContent.getInputDetails(field) :
+ null;
let params = {
agedWeight: this._agedWeight,
bucketSize: this._bucketSize,
expiryDate: 1000 * (Date.now() - this._expireDays * 24 * 60 * 60 * 1000),
fieldname: inputName,
fieldtype: field ? field.type : null,
maxTimeGroupings: this._maxTimeGroupings,
timeGroupingSize: this._timeGroupingSize,
prefixWeight: this._prefixWeight,
boundaryWeight: this._boundaryWeight,
+ heuristicsFieldType: heuristics ? heuristics.fieldName : null,
};
this.stopAutoCompleteSearch();
client.requestAutoCompleteResults(searchString, params, (entries) => {
this._pendingClient = null;
callback(entries);
});
this._pendingClient = client;