Bug 1300996 - Part 2: Show preview text on and highlight the fields that would be filled. r=MattN, lchang

MozReview-Commit-ID: DMgVhz2lvZ1

--HG--
extra : rebase_source : 76324146c8293426696748d4144340596355819c
This commit is contained in:
Ray Lin 2017-04-24 10:55:29 +08:00
Родитель 585a2083f7
Коммит 7b40abbb1e
2 изменённых файлов: 88 добавлений и 18 удалений

Просмотреть файл

@ -29,6 +29,8 @@ FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
function FormAutofillHandler(form) { function FormAutofillHandler(form) {
this.form = form; this.form = form;
this.fieldDetails = []; this.fieldDetails = [];
this.winUtils = this.form.rootElement.ownerGlobal.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
} }
FormAutofillHandler.prototype = { FormAutofillHandler.prototype = {
@ -57,6 +59,23 @@ FormAutofillHandler.prototype = {
*/ */
filledProfileGUID: null, filledProfileGUID: null,
/**
* A WindowUtils reference of which Window the form belongs
*/
winUtils: null,
/**
* Enum for form autofill MANUALLY_MANAGED_STATES values
*/
fieldStateEnum: {
// not themed
NORMAL: null,
// highlighted
AUTO_FILLED: "-moz-autofill",
// highlighted && grey color text
PREVIEW: "-moz-autofill-preview",
},
/** /**
* Set fieldDetails from the form about fields that can be autofilled. * Set fieldDetails from the form about fields that can be autofilled.
*/ */
@ -87,16 +106,16 @@ FormAutofillHandler.prototype = {
// 4. value already chosen in select element // 4. value already chosen in select element
let element = fieldDetail.elementWeakRef.get(); let element = fieldDetail.elementWeakRef.get();
if (!element || element === focusedInput) { if (!element) {
continue; continue;
} }
let value = profile[fieldDetail.fieldName]; let value = profile[fieldDetail.fieldName];
if (element instanceof Ci.nsIDOMHTMLInputElement && value) { if (element instanceof Ci.nsIDOMHTMLInputElement && !element.value && value) {
if (element.value) { if (element !== focusedInput) {
continue; element.setUserInput(value);
} }
element.setUserInput(value); this.changeFieldState(fieldDetail, "AUTO_FILLED");
} else if (element instanceof Ci.nsIDOMHTMLSelectElement) { } else if (element instanceof Ci.nsIDOMHTMLSelectElement) {
for (let option of element.options) { for (let option of element.options) {
if (value === option.textContent || value === option.value) { if (value === option.textContent || value === option.value) {
@ -110,10 +129,12 @@ FormAutofillHandler.prototype = {
option.selected = true; option.selected = true;
element.dispatchEvent(new Event("input", {"bubbles": true})); element.dispatchEvent(new Event("input", {"bubbles": true}));
element.dispatchEvent(new Event("change", {"bubbles": true})); element.dispatchEvent(new Event("change", {"bubbles": true}));
this.changeFieldState(fieldDetail, "AUTO_FILLED");
break; break;
} }
} }
} }
element.previewValue = "";
} }
}, },
@ -125,33 +146,81 @@ FormAutofillHandler.prototype = {
*/ */
previewFormFields(profile) { previewFormFields(profile) {
log.debug("preview profile in autofillFormFields:", profile); log.debug("preview profile in autofillFormFields:", profile);
/*
for (let fieldDetail of this.fieldDetails) { for (let fieldDetail of this.fieldDetails) {
let element = fieldDetail.elementWeakRef.get();
let value = profile[fieldDetail.fieldName] || ""; let value = profile[fieldDetail.fieldName] || "";
// Skip the fields that already has text entered // Skip the field that is null or already has text entered
if (fieldDetail.element.value) { if (!element || element.value) {
continue; continue;
} }
// TODO: Set highlight style and preview text. element.previewValue = value;
this.changeFieldState(fieldDetail, value ? "PREVIEW" : "NORMAL");
} }
*/
}, },
/**
* Clear preview text and background highlight of all fields.
*/
clearPreviewedFormFields() { clearPreviewedFormFields() {
log.debug("clear previewed fields in:", this.form); log.debug("clear previewed fields in:", this.form);
/*
for (let fieldDetail of this.fieldDetails) {
// TODO: Clear preview text
// We keep the highlight of all fields if this form has for (let fieldDetail of this.fieldDetails) {
// already been auto-filled with a profile. let element = fieldDetail.elementWeakRef.get();
if (this.filledProfileGUID == null) { if (!element) {
// TODO: Remove highlight style log.warn(fieldDetail.fieldName, "is unreachable");
continue;
}
element.previewValue = "";
// We keep the state if this field has
// already been auto-filled.
if (fieldDetail.state === "AUTO_FILLED") {
continue;
}
this.changeFieldState(fieldDetail, "NORMAL");
}
},
/**
* Change the state of a field to correspond with different presentations.
*
* @param {Object} fieldDetail
* A fieldDetail of which its element is about to update the state.
* @param {string} nextState
* Used to determine the next state
*/
changeFieldState(fieldDetail, nextState) {
let element = fieldDetail.elementWeakRef.get();
if (!element) {
log.warn(fieldDetail.fieldName, "is unreachable while changing state");
return;
}
if (!(nextState in this.fieldStateEnum)) {
log.warn(fieldDetail.fieldName, "is trying to change to an invalid state");
return;
}
for (let [state, mmStateValue] of Object.entries(this.fieldStateEnum)) {
// The NORMAL state is simply the absence of other manually
// managed states so we never need to add or remove it.
if (!mmStateValue) {
continue;
}
if (state == nextState) {
this.winUtils.addManuallyManagedState(element, mmStateValue);
} else {
this.winUtils.removeManuallyManagedState(element, mmStateValue);
} }
} }
*/
fieldDetail.state = nextState;
}, },
/** /**

Просмотреть файл

@ -35,6 +35,7 @@ xul|richlistitem[originaltype="autofill-profile"][selected="true"] > .profile-it
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
background-color: #FFFFFF;
color: -moz-FieldText color: -moz-FieldText
} }