User:P.A./Form user experience improvements
Contents
Overview
Submitting information to visited websites, using a web form or similar mechanism, is an increasingly common use case on the Internet.
Web forms are currently the preferred way for websites to ask the user for different classes of information:
- Common personal information, for example a name and address for shipping a product.
- Other identifying information that may be specific to one website, for example a username.
- Authentication of identity using a secret key, for example a password.
- Authentication and authorization of payments using secret credit card data.
- Recurring input that may be specific to one website, for example search terms.
- Information that may be reused on different websites, for example the e-mail address of a contact.
- Miscellaneous information that is entered only once, for example a message.
Each class of information has different characteristics, but most of them can generally benefit from a mechanism that is able to remember past input and help the user in entering the same data again, on either the same website or a different one.
Benefits
A good web form user experience, that takes into account previous input, is beneficial to both users and websites:
- Users will not need to spend time entering the same information again and again on different websites.
- Users returning to a website may authenticate more quickly using their stored username and password.
- Websites can have a lower barrier to entry when registering new users.
- Websites could accept payments with an easy user experience, but without the complex requirements created by storing credit card data on the server.
Themes
To offer a good user experience for all the different classes of information, the web browser needs to:
- Identify which class of information is being requested by the website.
- For complex data, this includes determining which input field corresponds to which part of the information.
- Collect and store data in the most reusable form.
- This includes building an accurate, reusable user profile from the available input.
- Adapt to different expected input in different websites.
- For example, deal with two separate name and surname fields or one single full name field.
- Different websites may have different field validation rules.
- Store and provide secret keys and data securely.
- Provide the simplest experience for completing the current task.
- For example, identify when a validation rule applies, and prevent the need of editing the data every time.
- The experience should be consistent across websites, so that if two websites look the same, the browser provides a similar experience with both of them.
There are current and proposed web APIs that websites my use to help the browser in solving these problems, but even for websites that don't use them, the browser should offer a solution that improves the overall experience.
Authors may be helped with upgrading their website to provide a better form experience with several actions:
- Provide meaningful console error messages and suggestions in the browser.
- These messages should be available by default to users of developer tools in Firefox.
- For example, indicate why the type of a field cannot be recognized.
- Define and evangelize best practices for websites.
- For example, a full name field is encouraged over separate name and surname fields.
- Encourage sites to adopt new web features.
- For example, the
autocomplete
attribute and therequestAutocomplete
method.
- For example, the
Approaches
The general problems stated above may be solved in several different ways, some of which have already been implemented in Firefox for a long time.
Login Manager
This existing feature stores usernames and passwords for future input.
- Populates username and password fields only.
- The username may be an e-mail address, but this is independent from the user profile.
- The list of available usernames and associated passwords is specific to a particular website.
- This feature is often used with only a single username and associated password for each website.
- May fill in the required information automatically once the user authorized the website.
Form History
This existing feature remembers past input in single-line text fields.
- Populates only one field at a time.
- Which list of past values is used depends only on an identifier provided by the website.
- The identifier is the HTML
name
orid
attribute.
- The identifier is the HTML
- Past values are shared across all websites.
- Requires explicit user action on the individual field.
- This can be clicking to show the list of past values, or typing to search.
Unrelated data can easily be mixed if different websites reuse the identifier with different meanings. Conversely, data cannot be reused if websites don't use the same identifier.
Form Autofill
This unimplemented feature remembers past input for common data sets, like personal information, that are generally shared across websites.
- Populates several related fields at a time.
- Past values are shared across all websites.
- May fill in the required information automatically once the user authorized the website.
requestAutocomplete
This unimplemented feature allows websites to explicitly request personal information from the browser.
- Replaces in-page form fields with a browser-provided interface.
- The browser may provide a different input experience depending on the device.
- Provides a similar input experience across all websites.
- Past values are shared across all websites.
- May fill in the required information automatically once the user authorized the website.
This feature works by transmitting the information to the server using hidden form fields after the website requested the browser to display the interface.
The website may display visible fields later in the process to correct any data validation errors.
Comparison of strategies
One of the most difficult problems that form autofill has to deal with, for existing websites, is identifying which type of data is being requested by each form field. Authors can update the website to use the autocomplete
attribute to help the browser, but the feature may not be available if the website doesn't do this. This can make it unclear to the user why one website supports autofill and another similarly-looking site doesn't.
On the other hand, requestAutocomplete only works with websites that have changed their input flow to explicitly request some personal information from the browser. This feature shows a browser-provided interface that provides data to the website. While the feature could be used in an "unclear" way to populate visible fields, similarly to form autofill, we can ensure that the difference is clear by requiring that target form fields are hidden at the time of the request to autocomplete them.
Implementation
Existing features
Most of the main and support code for Login Manager and Form History can be found in these source folders and files:
-
toolkit/components/autocomplete/
-
toolkit/components/passwordmgr/
-
toolkit/components/satchel/
-
toolkit/content/widgets/autocomplete.xml
Suggesting past input
The autocompletion mechanism has the following typical control flow:
- The main entry point is the global
@mozilla.org/satchel/form-fill-controller;1
service implemented innsFormFillController.cpp
. - All
<browser>
elements with anautocompletepopup
attribute, at the time of thepageshow
event, callnsIFormFillController.attachToBrowser
on the global service. - When an input field raises the
focus
event,nsFormFillController::Focus
checks if autocompletion should be enabled, in which case it registers the input field with the global@mozilla.org/autocomplete/controller;1
service, and starts forwarding input events tonsIAutoCompleteController
.- The
nsFormFillController::GetSearchAt
method returnsform-history
, indicating that searches should be handled by the@mozilla.org/autocomplete/search;1?name=form-history
global service, which is the same service implemented innsFormFillController.cpp
.
- The
- At this point, typically while typing,
nsAutoCompleteController::HandleText
starts searches by calling thensFormFillController::StartSearch
method.- Note that the
nsIAutoCompleteInput.searchParam
getter of the same global service provides one of the parameters of the function.
- Note that the
- The
StartSearch
method dispatches the call throughautoCompleteSearch
orautoCompleteSearchAsync
to either:- Login Manager, through the global
@mozilla.org/login-manager;1
service. - Form History, through the global
@mozilla.org/satchel/form-autocomplete;1
service.
- Login Manager, through the global
- When the result is available,
nsFormFillController.cpp
invokes thensAutoCompleteController::OnSearchResult
method.- This stores the result in the global service implemented in
nsAutoCompleteController.cpp
. - This calls
nsIAutoCompletePopup.invalidate
, and also indirectlynsIAutoCompletePopup.openAutocompletePopup
, on the entry returned bynsFormFillController::GetPopup
, which is theautocompletepopup
associated to the browser window.- The
openAutocompletePopup
method is called with a reference to thensIAutoCompleteInput
corresponding to the global service implemented innsFormFillController.cpp
.
- The
- This stores the result in the global service implemented in
- The
nsIAutoCompletePopup
interface will display the popup and handle its input.- This may cause the actual calls to be routed through IPC in case the interface is invoked in a child process.
- In response to popup events, the contents of the
input
field are updated.
Recording new input
When a form is submitted, saving the submitted data is handled by a different mechanism:
- The main entry point is the global
@mozilla.org/satchel/form-history-startup;1
service implemented inFormHistoryStartup.js
. - This registers the global
formSubmitListener.js
content script for all browsers. - Form submissions monitored by the content script are translated into
FormHistory.jsm
calls to update the stored data.
Bug list
- bug 1009935 - Implement the @autocomplete attribute for values other than off/on
- bug 939351 - Implement requestAutocomplete backend
- bug 946022 - Implement requestAutocomplete for Firefox for Android
- bug 990367 - requestAutocomplete UI for Firefox desktop
- bug 998077 - Sync support for autofill data
- bug 1007176 - Implement requestAutocomplete on donate.mozilla.org
- bug 1007181 - Project Review: requestAutoComplete on donate.mozilla.org