| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_AUTOFILL_CONTENT_RENDERER_FORM_AUTOFILL_UTIL_H_ |
| #define COMPONENTS_AUTOFILL_CONTENT_RENDERER_FORM_AUTOFILL_UTIL_H_ |
| |
| #include <stddef.h> |
| |
| #include <set> |
| #include <vector> |
| |
| #include "base/macros.h" |
| #include "base/strings/string16.h" |
| #include "components/autofill/core/common/autofill_constants.h" |
| #include "components/autofill/core/common/password_form_field_prediction_map.h" |
| #include "third_party/blink/public/platform/web_vector.h" |
| #include "third_party/blink/public/web/web_element_collection.h" |
| #include "ui/gfx/geometry/rect_f.h" |
| |
| class GURL; |
| |
| namespace blink { |
| enum class WebAutofillState; |
| |
| class WebDocument; |
| class WebElement; |
| class WebFormControlElement; |
| class WebFormElement; |
| class WebInputElement; |
| class WebLocalFrame; |
| class WebNode; |
| } |
| |
| namespace autofill { |
| |
| struct FormData; |
| struct FormFieldData; |
| |
| class FieldDataManager; |
| |
| namespace form_util { |
| |
| // A bit field mask to extract data from WebFormControlElement. |
| // Copied to components/autofill/ios/browser/resources/autofill_controller.js. |
| enum ExtractMask { |
| EXTRACT_NONE = 0, |
| EXTRACT_VALUE = 1 << 0, // Extract value from WebFormControlElement. |
| EXTRACT_OPTION_TEXT = 1 << 1, // Extract option text from |
| // WebFormSelectElement. Only valid when |
| // |EXTRACT_VALUE| is set. |
| // This is used for form submission where |
| // human readable value is captured. |
| EXTRACT_OPTIONS = 1 << 2, // Extract options from |
| // WebFormControlElement. |
| }; |
| |
| // The maximum number of form fields we are willing to parse, due to |
| // computational costs. Several examples of forms with lots of fields that are |
| // not relevant to Autofill: (1) the Netflix queue; (2) the Amazon wishlist; |
| // (3) router configuration pages; and (4) other configuration pages, e.g. for |
| // Google code project settings. |
| // Copied to components/autofill/ios/browser/resources/autofill_controller.js. |
| extern const size_t kMaxParseableFields; |
| |
| // Helper function that strips any authentication data, as well as query and |
| // ref portions of URL |
| GURL StripAuthAndParams(const GURL& gurl); |
| |
| // Extract FormData from the form element and return whether the operation was |
| // successful. |
| bool ExtractFormData(const blink::WebFormElement& form_element, FormData* data); |
| |
| // Helper function to check if there exist any visible form on |frame| which |
| // equals |form_element|. If |form_element| is null, checks if forms action |
| // equals |action|. Returns true if so. For forms with empty or unspecified |
| // actions, all form data are used for comparison. |
| bool IsFormVisible(blink::WebLocalFrame* frame, |
| const blink::WebFormElement& form_element, |
| const GURL& action, |
| const GURL& origin, |
| const FormData& form_data); |
| |
| // Returns true if at least one element from |control_elements| is visible. |
| bool IsSomeControlElementVisible( |
| const blink::WebVector<blink::WebFormControlElement>& control_elements); |
| |
| // Returns true if some control elements of |form| are visible. |
| bool AreFormContentsVisible(const blink::WebFormElement& form); |
| |
| // Helper functions to assist in getting the canonical form of the action and |
| // origin. The action will proplerly take into account <BASE>, and both will |
| // strip unnecessary data (e.g. query params and HTTP credentials). |
| GURL GetCanonicalActionForForm(const blink::WebFormElement& form); |
| GURL GetCanonicalOriginForDocument(const blink::WebDocument& document); |
| |
| // Returns true if |element| is a month input element. |
| bool IsMonthInput(const blink::WebInputElement* element); |
| |
| // Returns true if |element| is a text input element. |
| bool IsTextInput(const blink::WebInputElement* element); |
| |
| // Returns true if |element| is a select element. |
| bool IsSelectElement(const blink::WebFormControlElement& element); |
| |
| // Returns true if |element| is a textarea element. |
| bool IsTextAreaElement(const blink::WebFormControlElement& element); |
| |
| // Returns true if |element| is a checkbox or a radio button element. |
| bool IsCheckableElement(const blink::WebInputElement* element); |
| |
| // Returns true if |element| is one of the input element types that can be |
| // autofilled. {Text, Radiobutton, Checkbox}. |
| bool IsAutofillableInputElement(const blink::WebInputElement* element); |
| |
| // Returns true if |element| is one of the element types that can be autofilled. |
| // {Text, Radiobutton, Checkbox, Select, TextArea}. |
| bool IsAutofillableElement(const blink::WebFormControlElement& element); |
| |
| // True if this node can take focus. If layout is blocked, then the function |
| // checks if the element takes up space in the layout, ie. this element or a |
| // descendant has a non-empty bounding bounding client rect. |
| bool IsWebElementVisible(const blink::WebElement& element); |
| |
| // Returns the form's |name| attribute if non-empty; otherwise the form's |id| |
| // attribute. |
| const base::string16 GetFormIdentifier(const blink::WebFormElement& form); |
| |
| // Returns text alignment for |element|. |
| base::i18n::TextDirection GetTextDirectionForElement( |
| const blink::WebFormControlElement& element); |
| |
| // Returns all the auto-fillable form control elements in |control_elements|. |
| std::vector<blink::WebFormControlElement> ExtractAutofillableElementsFromSet( |
| const blink::WebVector<blink::WebFormControlElement>& control_elements); |
| |
| // Returns all the auto-fillable form control elements in |form_element|. |
| std::vector<blink::WebFormControlElement> ExtractAutofillableElementsInForm( |
| const blink::WebFormElement& form_element); |
| |
| // Fills out a FormField object from a given WebFormControlElement. |
| // |extract_mask|: See the enum ExtractMask above for details. Field properties |
| // will be copied from |field_data_manager|, if the argument is not null and |
| // has entry for |element| (see properties in FieldPropertiesFlags). |
| void WebFormControlElementToFormField( |
| const blink::WebFormControlElement& element, |
| const FieldDataManager* field_data_manager, |
| ExtractMask extract_mask, |
| FormFieldData* field); |
| |
| // Fills |form| with the FormData object corresponding to the |form_element|. |
| // If |field| is non-NULL, also fills |field| with the FormField object |
| // corresponding to the |form_control_element|. |extract_mask| controls what |
| // data is extracted. Returns true if |form| is filled out. Also returns false |
| // if there are no fields or too many fields in the |form|. Field properties |
| // will be copied from |field_data_manager|, if the argument is not null and |
| // has entry for |element| (see properties in FieldPropertiesFlags). |
| bool WebFormElementToFormData( |
| const blink::WebFormElement& form_element, |
| const blink::WebFormControlElement& form_control_element, |
| const FieldDataManager* field_data_manager, |
| ExtractMask extract_mask, |
| FormData* form, |
| FormFieldData* field); |
| |
| // Get all form control elements from |elements| that are not part of a form. |
| // If |fieldsets| is not NULL, also append the fieldsets encountered that are |
| // not part of a form. |
| std::vector<blink::WebFormControlElement> GetUnownedFormFieldElements( |
| const blink::WebElementCollection& elements, |
| std::vector<blink::WebElement>* fieldsets); |
| |
| // A shorthand for filtering the results of GetUnownedFormFieldElements with |
| // ExtractAutofillableElementsFromSet. |
| std::vector<blink::WebFormControlElement> |
| GetUnownedAutofillableFormFieldElements( |
| const blink::WebElementCollection& elements, |
| std::vector<blink::WebElement>* fieldsets); |
| |
| // Fills |form| with the form data derived from |fieldsets|, |control_elements| |
| // and |origin|. If |field| is non-NULL, fill it with the FormField |
| // representation for |element|. |
| // |extract_mask| usage and the return value are the same as |
| // WebFormElementToFormData() above. |
| // This function will return false and not perform any extraction if |
| // |document| does not pertain to checkout. |
| bool UnownedCheckoutFormElementsAndFieldSetsToFormData( |
| const std::vector<blink::WebElement>& fieldsets, |
| const std::vector<blink::WebFormControlElement>& control_elements, |
| const blink::WebFormControlElement* element, |
| const blink::WebDocument& document, |
| ExtractMask extract_mask, |
| FormData* form, |
| FormFieldData* field); |
| |
| // Same as above, but without the requirement that the elements only be |
| // related to checkout. Field properties of |control_elements| will be copied |
| // from |field_data_manager|, if the argument is not null and has corresponding |
| // entries (see properties in FieldPropertiesFlags). |
| bool UnownedPasswordFormElementsAndFieldSetsToFormData( |
| const std::vector<blink::WebElement>& fieldsets, |
| const std::vector<blink::WebFormControlElement>& control_elements, |
| const blink::WebFormControlElement* element, |
| const blink::WebDocument& document, |
| const FieldDataManager* field_data_manager, |
| ExtractMask extract_mask, |
| FormData* form, |
| FormFieldData* field); |
| |
| // Finds the form that contains |element| and returns it in |form|. If |field| |
| // is non-NULL, fill it with the FormField representation for |element|. |
| // Returns false if the form is not found or cannot be serialized. |
| bool FindFormAndFieldForFormControlElement( |
| const blink::WebFormControlElement& element, |
| FormData* form, |
| FormFieldData* field); |
| |
| // Fills the form represented by |form|. |element| is the input element that |
| // initiated the auto-fill process. |
| void FillForm(const FormData& form, |
| const blink::WebFormControlElement& element); |
| |
| // Fills focusable and non-focusable form control elements within |form_element| |
| // with field data from |form_data|. |
| void FillFormIncludingNonFocusableElements( |
| const FormData& form_data, |
| const blink::WebFormElement& form_element); |
| |
| // Previews the form represented by |form|. |element| is the input element that |
| // initiated the preview process. |
| void PreviewForm(const FormData& form, |
| const blink::WebFormControlElement& element); |
| |
| // Clears the placeholder values and the auto-filled background for any fields |
| // in the form containing |node| that have been previewed. Resets the |
| // autofilled state of |node| to |was_autofilled|. Returns false if the form is |
| // not found. |
| bool ClearPreviewedFormWithElement(const blink::WebFormControlElement& element, |
| blink::WebAutofillState old_autofill_state); |
| |
| // Checks if the webpage is empty. |
| // This kind of webpage is considered as empty: |
| // <html> |
| // <head> |
| // <head/> |
| // <body> |
| // <body/> |
| // <html/> |
| // Meta, script and title tags don't influence the emptiness of a webpage. |
| bool IsWebpageEmpty(const blink::WebLocalFrame* frame); |
| |
| // This function checks whether the children of |element| |
| // are of the type <script>, <meta>, or <title>. |
| bool IsWebElementEmpty(const blink::WebElement& element); |
| |
| // Previews |suggestion| in |input_element| and highlights the suffix of |
| // |suggestion| not included in the |input_element| text. |input_element| must |
| // not be null. |user_input| should be the text typed by the user into |
| // |input_element|. Note that |user_input| cannot be easily derived from |
| // |input_element| by calling value(), because of http://crbug.com/507714. |
| void PreviewSuggestion(const base::string16& suggestion, |
| const base::string16& user_input, |
| blink::WebFormControlElement* input_element); |
| |
| // Returns the aggregated values of the descendants of |element| that are |
| // non-empty text nodes. This is a faster alternative to |innerText()| for |
| // performance critical operations. It does a full depth-first search so can be |
| // used when the structure is not directly known. However, unlike with |
| // |innerText()|, the search depth and breadth are limited to a fixed threshold. |
| // Whitespace is trimmed from text accumulated at descendant nodes. |
| base::string16 FindChildText(const blink::WebNode& node); |
| |
| // Exposed for testing purpose |
| base::string16 FindChildTextWithIgnoreListForTesting( |
| const blink::WebNode& node, |
| const std::set<blink::WebNode>& divs_to_skip); |
| bool InferLabelForElementForTesting(const blink::WebFormControlElement& element, |
| const std::vector<base::char16>& stop_words, |
| base::string16* label, |
| FormFieldData::LabelSource* label_source); |
| base::string16 InferButtonTitleForTesting( |
| const blink::WebFormElement& form_element); |
| |
| // Returns form by unique renderer id. Return null element if there is no form |
| // with given form renderer id. |
| blink::WebFormElement FindFormByUniqueRendererId(blink::WebDocument doc, |
| uint32_t form_renderer_id); |
| |
| // Note: The vector-based API of the following two functions is a tax for limiting |
| // the frequency and duration of retrieving a lot of DOM elements. Alternative |
| // solutions have been discussed on https://crrev.com/c/1108201. |
| |
| // Returns form control elements by unique renderer id. The result has the same |
| // number elements as |form_control_renderer_ids| and i-th element of the result |
| // corresponds to the i-th element of |form_control_renderer_ids|. |
| // |form_control_renderer_ids| is supposed to be small (<=10 elements), because |
| // it is being frequently searched by linear pass over its elements. |
| // The call of this function might be time expensive, because it retrieves all |
| // DOM elements. |
| std::vector<blink::WebFormControlElement> |
| FindFormControlElementsByUniqueRendererId( |
| blink::WebDocument doc, |
| const std::vector<uint32_t>& form_control_renderer_ids); |
| |
| // Returns form control elements by unique renderer id from the form with unique |
| // id |form_renderer_id|. The result has the same number elements as |
| // |form_control_renderer_ids| and i-th element of the result corresponds to the |
| // i-th element of |form_control_renderer_ids|. |
| // |form_control_renderer_ids| is supposed to be small (<=10 elements), because |
| // it is being frequently searched by linear pass over its elements. |
| // This function is faster than the previous one, because it only retrieves form |
| // control elements from a single form. |
| std::vector<blink::WebFormControlElement> |
| FindFormControlElementsByUniqueRendererId( |
| blink::WebDocument doc, |
| uint32_t form_renderer_id, |
| const std::vector<uint32_t>& form_control_renderer_ids); |
| |
| // Returns the ARIA label text of the elements denoted by the aria-labelledby |
| // attribute of |element| or the value of the aria-label attribute of |
| // |element|, with priority given to the aria-labelledby attribute. |
| base::string16 GetAriaLabel(const blink::WebDocument& document, |
| const blink::WebFormControlElement& element); |
| |
| // Returns the ARIA label text of the elements denoted by the aria-describedby |
| // attribute of |element|. |
| base::string16 GetAriaDescription(const blink::WebDocument& document, |
| const blink::WebFormControlElement& element); |
| |
| } // namespace form_util |
| } // namespace autofill |
| |
| #endif // COMPONENTS_AUTOFILL_CONTENT_RENDERER_FORM_AUTOFILL_UTIL_H_ |