User:P.A./Form user experience improvements

From MozillaWiki
Jump to: navigation, search

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 the requestAutocomplete method.

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 or id attribute.
  • 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:

  1. The main entry point is the global @mozilla.org/satchel/form-fill-controller;1 service implemented in nsFormFillController.cpp.
  2. All <browser> elements with an autocompletepopup attribute, at the time of the pageshow event, call nsIFormFillController.attachToBrowser on the global service.
  3. 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 to nsIAutoCompleteController.
    • The nsFormFillController::GetSearchAt method returns form-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 in nsFormFillController.cpp.
  4. At this point, typically while typing, nsAutoCompleteController::HandleText starts searches by calling the nsFormFillController::StartSearch method.
    • Note that the nsIAutoCompleteInput.searchParam getter of the same global service provides one of the parameters of the function.
  5. The StartSearch method dispatches the call through autoCompleteSearch or autoCompleteSearchAsync 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.
  6. When the result is available, nsFormFillController.cpp invokes the nsAutoCompleteController::OnSearchResult method.
    • This stores the result in the global service implemented in nsAutoCompleteController.cpp.
    • This calls nsIAutoCompletePopup.invalidate, and also indirectly nsIAutoCompletePopup.openAutocompletePopup, on the entry returned by nsFormFillController::GetPopup, which is the autocompletepopup associated to the browser window.
      • The openAutocompletePopup method is called with a reference to the nsIAutoCompleteInput corresponding to the global service implemented in nsFormFillController.cpp.
  7. 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.
  8. 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:

  1. The main entry point is the global @mozilla.org/satchel/form-history-startup;1 service implemented in FormHistoryStartup.js.
  2. This registers the global formSubmitListener.js content script for all browsers.
  3. 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

References