1 /* 2 * Copyright (c) 2010 The Chromium Authors. All rights reserved. 3 * Copyright 2010, The Android Open Source Project 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "config.h" 28 #include "FormManagerAndroid.h" 29 30 #include "DocumentLoader.h" 31 #include "Element.h" 32 #include "Frame.h" 33 #include "FrameLoader.h" 34 #include "HTMLCollection.h" 35 #include "HTMLFormControlElement.h" 36 #include "HTMLFormElement.h" 37 #include "HTMLInputElement.h" 38 #include "HTMLLabelElement.h" 39 #include "HTMLNames.h" 40 #include "HTMLOptionElement.h" 41 #include "HTMLSelectElement.h" 42 #include "InputElement.h" 43 #include "Node.h" 44 #include "NodeList.h" 45 #include "HTMLCollection.h" 46 #include "FormAssociatedElement.h" 47 #include "QualifiedName.h" 48 #include "StringUtils.h" 49 50 // TODO: This file is taken from chromium/chrome/renderer/form_manager.cc and 51 // customised to use WebCore types rather than WebKit API types. It would be 52 // nice and would ease future merge pain if the two could be combined. 53 54 using webkit_glue::FormData; 55 using webkit_glue::FormField; 56 using WebCore::Element; 57 using WebCore::FormAssociatedElement; 58 using WebCore::HTMLCollection; 59 using WebCore::HTMLElement; 60 using WebCore::HTMLFormControlElement; 61 using WebCore::HTMLFormElement; 62 using WebCore::HTMLInputElement; 63 using WebCore::HTMLLabelElement; 64 using WebCore::HTMLOptionElement; 65 using WebCore::HTMLSelectElement; 66 using WebCore::InputElement; 67 using WebCore::Node; 68 using WebCore::NodeList; 69 70 using namespace WebCore::HTMLNames; 71 72 namespace { 73 74 // Android helper function. 75 HTMLInputElement* HTMLFormControlElementToHTMLInputElement(const HTMLFormControlElement& element) { 76 Node* node = const_cast<Node*>(static_cast<const Node*>(&element)); 77 InputElement* input_element = node->toInputElement(); 78 if (node && node->isHTMLElement()) 79 return static_cast<HTMLInputElement*>(input_element); 80 81 return 0; 82 } 83 84 // The number of fields required by Autofill. Ideally we could send the forms 85 // to Autofill no matter how many fields are in the forms; however, finding the 86 // label for each field is a costly operation and we can't spare the cycles if 87 // it's not necessary. 88 // Note the on ANDROID we reduce this from Chromium's 3 as it allows us to 89 // Autofill simple name/email forms for example. This improves the mobile 90 // device experience where form filling can be time consuming and frustrating. 91 const size_t kRequiredAutofillFields = 2; 92 93 // The maximum number of form fields we are willing to parse, due to 94 // computational costs. This is a very conservative upper bound. 95 const size_t kMaxParseableFields = 1000; 96 97 // The maximum length allowed for form data. 98 const size_t kMaxDataLength = 1024; 99 100 // In HTML5, all text fields except password are text input fields to 101 // autocomplete. 102 bool IsTextInput(const HTMLInputElement* element) { 103 if (!element) 104 return false; 105 106 return element->isTextField() && !element->isPasswordField(); 107 } 108 109 bool IsSelectElement(const HTMLFormControlElement& element) { 110 return formControlType(element) == kSelectOne; 111 } 112 113 bool IsOptionElement(Element& element) { 114 return element.hasTagName(optionTag); 115 } 116 117 bool IsAutofillableElement(const HTMLFormControlElement& element) { 118 HTMLInputElement* html_input_element = HTMLFormControlElementToHTMLInputElement(element); 119 return (html_input_element && IsTextInput(html_input_element)) || IsSelectElement(element); 120 } 121 122 // This is a helper function for the FindChildText() function (see below). 123 // Search depth is limited with the |depth| parameter. 124 string16 FindChildTextInner(Node* node, int depth) { 125 string16 element_text; 126 if (!node || depth <= 0) 127 return element_text; 128 129 string16 node_text = WTFStringToString16(node->nodeValue()); 130 TrimWhitespace(node_text, TRIM_ALL, &node_text); 131 if (!node_text.empty()) 132 element_text = node_text; 133 134 string16 child_text = FindChildTextInner(node->firstChild(), depth-1); 135 if (!child_text.empty()) 136 element_text = element_text + child_text; 137 138 string16 sibling_text = FindChildTextInner(node->nextSibling(), depth-1); 139 if (!sibling_text.empty()) 140 element_text = element_text + sibling_text; 141 142 return element_text; 143 } 144 145 // Returns the aggregated values of the decendants or siblings of |element| that 146 // are non-empty text nodes. This is a faster alternative to |innerText()| for 147 // performance critical operations. It does a full depth-first search so can be 148 // used when the structure is not directly known. Whitesapce is trimmed from 149 // text accumulated at descendant and sibling. Search is limited to within 10 150 // siblings and/or descendants. 151 string16 FindChildText(Element* element) { 152 Node* child = element->firstChild(); 153 154 const int kChildSearchDepth = 10; 155 return FindChildTextInner(child, kChildSearchDepth); 156 } 157 158 // Helper for |InferLabelForElement()| that infers a label, if possible, from 159 // a previous node of |element|. 160 string16 InferLabelFromPrevious(const HTMLFormControlElement& element) { 161 string16 inferred_label; 162 Node* previous = element.previousSibling(); 163 if (!previous) 164 return string16(); 165 166 if (previous->isTextNode()) { 167 inferred_label = WTFStringToString16(previous->nodeValue()); 168 TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label); 169 } 170 171 // If we didn't find text, check for previous paragraph. 172 // Eg. <p>Some Text</p><input ...> 173 // Note the lack of whitespace between <p> and <input> elements. 174 if (inferred_label.empty() && previous->isElementNode()) { 175 Element* element = static_cast<Element*>(previous); 176 if (element->hasTagName(pTag)) 177 inferred_label = FindChildText(element); 178 } 179 180 // If we didn't find paragraph, check for previous paragraph to this. 181 // Eg. <p>Some Text</p> <input ...> 182 // Note the whitespace between <p> and <input> elements. 183 if (inferred_label.empty()) { 184 Node* sibling = previous->previousSibling(); 185 if (sibling && sibling->isElementNode()) { 186 Element* element = static_cast<Element*>(sibling); 187 if (element->hasTagName(pTag)) 188 inferred_label = FindChildText(element); 189 } 190 } 191 192 // Look for text node prior to <img> tag. 193 // Eg. Some Text<img/><input ...> 194 if (inferred_label.empty()) { 195 while (inferred_label.empty() && previous) { 196 if (previous->isTextNode()) { 197 inferred_label = WTFStringToString16(previous->nodeValue()); 198 TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label); 199 } else if (previous->isElementNode()) { 200 Element* element = static_cast<Element*>(previous); 201 if (!element->hasTagName(imgTag)) 202 break; 203 } else 204 break; 205 previous = previous->previousSibling(); 206 } 207 } 208 209 // Look for label node prior to <input> tag. 210 // Eg. <label>Some Text</label><input ...> 211 if (inferred_label.empty()) { 212 while (inferred_label.empty() && previous) { 213 if (previous->isTextNode()) { 214 inferred_label = WTFStringToString16(previous->nodeValue()); 215 TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label); 216 } else if (previous->isElementNode()) { 217 Element* element = static_cast<Element*>(previous); 218 if (element->hasTagName(labelTag)) { 219 inferred_label = FindChildText(element); 220 } else { 221 break; 222 } 223 } else { 224 break; 225 } 226 227 previous = previous->previousSibling(); 228 } 229 } 230 231 return inferred_label; 232 } 233 234 // Helper for |InferLabelForElement()| that infers a label, if possible, from 235 // surrounding table structure. 236 // Eg. <tr><td>Some Text</td><td><input ...></td></tr> 237 // Eg. <tr><td><b>Some Text</b></td><td><b><input ...></b></td></tr> 238 string16 InferLabelFromTable(const HTMLFormControlElement& element) { 239 string16 inferred_label; 240 Node* parent = element.parentNode(); 241 while (parent && parent->isElementNode() && !static_cast<Element*>(parent)->hasTagName(tdTag)) 242 parent = parent->parentNode(); 243 244 // Check all previous siblings, skipping non-element nodes, until we find a 245 // non-empty text block. 246 Node* previous = parent; 247 while(previous) { 248 if (previous->isElementNode()) { 249 Element* e = static_cast<Element*>(previous); 250 if (e->hasTagName(tdTag)) { 251 inferred_label = FindChildText(e); 252 if (!inferred_label.empty()) 253 break; 254 } 255 } 256 previous = previous->previousSibling(); 257 } 258 return inferred_label; 259 } 260 261 // Helper for |InferLabelForElement()| that infers a label, if possible, from 262 // a surrounding div table. 263 // Eg. <div>Some Text<span><input ...></span></div> 264 string16 InferLabelFromDivTable(const HTMLFormControlElement& element) { 265 Node* parent = element.parentNode(); 266 while (parent && parent->isElementNode() && !static_cast<Element*>(parent)->hasTagName(divTag)) 267 parent = parent->parentNode(); 268 269 if (!parent || !parent->isElementNode()) 270 return string16(); 271 272 Element* e = static_cast<Element*>(parent); 273 if (!e || !e->hasTagName(divTag)) 274 return string16(); 275 276 return FindChildText(e); 277 } 278 279 // Helper for |InferLabelForElement()| that infers a label, if possible, from 280 // a surrounding definition list. 281 // Eg. <dl><dt>Some Text</dt><dd><input ...></dd></dl> 282 // Eg. <dl><dt><b>Some Text</b></dt><dd><b><input ...></b></dd></dl> 283 string16 InferLabelFromDefinitionList(const HTMLFormControlElement& element) { 284 string16 inferred_label; 285 Node* parent = element.parentNode(); 286 while (parent && parent->isElementNode() && !static_cast<Element*>(parent)->hasTagName(ddTag)) 287 parent = parent->parentNode(); 288 289 if (parent && parent->isElementNode()) { 290 Element* element = static_cast<Element*>(parent); 291 if (element->hasTagName(ddTag)) { 292 Node* previous = parent->previousSibling(); 293 294 // Skip by any intervening text nodes. 295 while (previous && previous->isTextNode()) 296 previous = previous->previousSibling(); 297 298 if (previous && previous->isElementNode()) { 299 element = static_cast<Element*>(previous); 300 if (element->hasTagName(dtTag)) 301 inferred_label = FindChildText(element); 302 } 303 } 304 } 305 return inferred_label; 306 } 307 308 // Infers corresponding label for |element| from surrounding context in the DOM. 309 // Contents of preceding <p> tag or preceding text element found in the form. 310 string16 InferLabelForElement(const HTMLFormControlElement& element) { 311 string16 inferred_label = InferLabelFromPrevious(element); 312 313 // If we didn't find a label, check for table cell case. 314 if (inferred_label.empty()) 315 inferred_label = InferLabelFromTable(element); 316 317 // If we didn't find a label, check for div table case. 318 if (inferred_label.empty()) 319 inferred_label = InferLabelFromDivTable(element); 320 321 // If we didn't find a label, check for definition list case. 322 if (inferred_label.empty()) 323 inferred_label = InferLabelFromDefinitionList(element); 324 325 return inferred_label; 326 } 327 328 void GetOptionStringsFromElement(const HTMLSelectElement& select_element, std::vector<string16>* option_strings) { 329 DCHECK(option_strings); 330 option_strings->clear(); 331 WTF::Vector<Element*> list_items = select_element.listItems(); 332 option_strings->reserve(list_items.size()); 333 for (size_t i = 0; i < list_items.size(); ++i) { 334 if (IsOptionElement(*list_items[i])) { 335 option_strings->push_back(WTFStringToString16(static_cast<HTMLOptionElement*>(list_items[i])->value())); 336 } 337 } 338 } 339 340 // Returns the form's |name| attribute if non-empty; otherwise the form's |id| 341 // attribute. 342 const string16 GetFormIdentifier(const HTMLFormElement& form) { 343 string16 identifier = WTFStringToString16(form.name()); 344 if (identifier.empty()) 345 identifier = WTFStringToString16(form.getIdAttribute()); 346 return identifier; 347 } 348 349 } // namespace 350 351 namespace android { 352 353 struct FormManager::FormElement { 354 RefPtr<HTMLFormElement> form_element; 355 std::vector<RefPtr<HTMLFormControlElement> > control_elements; 356 std::vector<string16> control_values; 357 }; 358 359 FormManager::FormManager() { 360 } 361 362 FormManager::~FormManager() { 363 Reset(); 364 } 365 366 // static 367 void FormManager::HTMLFormControlElementToFormField(HTMLFormControlElement* element, ExtractMask extract_mask, FormField* field) { 368 DCHECK(field); 369 DCHECK(element); 370 371 // The label is not officially part of a HTMLFormControlElement; however, the 372 // labels for all form control elements are scraped from the DOM and set in 373 // WebFormElementToFormData. 374 field->name = nameForAutofill(*element); 375 field->form_control_type = formControlType(*element); 376 377 if (!IsAutofillableElement(*element)) 378 return; 379 380 HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*element); 381 382 if (IsTextInput(input_element)) { 383 field->max_length = input_element->maxLength(); 384 field->is_autofilled = input_element->isAutofilled(); 385 } else if (extract_mask & EXTRACT_OPTIONS) { 386 // Set option strings on the field is available. 387 DCHECK(IsSelectElement(*element)); 388 HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element); 389 std::vector<string16> option_strings; 390 GetOptionStringsFromElement(*select_element, &option_strings); 391 field->option_strings = option_strings; 392 } 393 394 if (!(extract_mask & EXTRACT_VALUE)) 395 return; 396 397 string16 value; 398 if (IsTextInput(input_element)) { 399 value = WTFStringToString16(input_element->value()); 400 } else { 401 DCHECK(IsSelectElement(*element)); 402 HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element); 403 value = WTFStringToString16(select_element->value()); 404 405 // Convert the |select_element| value to text if requested. 406 if (extract_mask & EXTRACT_OPTION_TEXT) { 407 Vector<Element*> list_items = select_element->listItems(); 408 for (size_t i = 0; i < list_items.size(); ++i) { 409 if (IsOptionElement(*list_items[i]) && 410 WTFStringToString16(static_cast<HTMLOptionElement*>(list_items[i])->value()) == value) { 411 value = WTFStringToString16(static_cast<HTMLOptionElement*>(list_items[i])->text()); 412 break; 413 } 414 } 415 } 416 } 417 418 // TODO: This is a temporary stop-gap measure designed to prevent 419 // a malicious site from DOS'ing the browser with extremely large profile 420 // data. The correct solution is to parse this data asynchronously. 421 // See http://crbug.com/49332. 422 if (value.size() > kMaxDataLength) 423 value = value.substr(0, kMaxDataLength); 424 425 field->value = value; 426 } 427 428 // static 429 string16 FormManager::LabelForElement(const HTMLFormControlElement& element) { 430 // Don't scrape labels for elements we can't possible autofill anyway. 431 if (!IsAutofillableElement(element)) 432 return string16(); 433 434 RefPtr<NodeList> labels = element.document()->getElementsByTagName("label"); 435 for (unsigned i = 0; i < labels->length(); ++i) { 436 Node* e = labels->item(i); 437 DCHECK(e->hasTagName(labelTag)); 438 HTMLLabelElement* label = static_cast<HTMLLabelElement*>(e); 439 if (label->control() == &element) 440 return FindChildText(label); 441 } 442 443 // Infer the label from context if not found in label element. 444 return InferLabelForElement(element); 445 } 446 447 // static 448 bool FormManager::HTMLFormElementToFormData(HTMLFormElement* element, RequirementsMask requirements, ExtractMask extract_mask, FormData* form) { 449 DCHECK(form); 450 451 Frame* frame = element->document()->frame(); 452 if (!frame) 453 return false; 454 455 if (requirements & REQUIRE_AUTOCOMPLETE && !element->autoComplete()) 456 return false; 457 458 form->name = GetFormIdentifier(*element); 459 form->method = WTFStringToString16(element->method()); 460 form->origin = GURL(WTFStringToString16(frame->loader()->documentLoader()->url().string())); 461 form->action = GURL(WTFStringToString16(frame->document()->completeURL(element->action()))); 462 form->user_submitted = element->wasUserSubmitted(); 463 464 // If the completed URL is not valid, just use the action we get from 465 // WebKit. 466 if (!form->action.is_valid()) 467 form->action = GURL(WTFStringToString16(element->action())); 468 469 // A map from a FormField's name to the FormField itself. 470 std::map<string16, FormField*> name_map; 471 472 // The extracted FormFields. We use pointers so we can store them in 473 // |name_map|. 474 ScopedVector<FormField> form_fields; 475 476 WTF::Vector<WebCore::FormAssociatedElement*> control_elements = element->associatedElements(); 477 478 // A vector of bools that indicate whether each field in the form meets the 479 // requirements and thus will be in the resulting |form|. 480 std::vector<bool> fields_extracted(control_elements.size(), false); 481 482 for (size_t i = 0; i < control_elements.size(); ++i) { 483 if (!control_elements[i]->isFormControlElement()) 484 continue; 485 486 HTMLFormControlElement* control_element = static_cast<HTMLFormControlElement*>(control_elements[i]); 487 488 if(!IsAutofillableElement(*control_element)) 489 continue; 490 491 HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*control_element); 492 if (requirements & REQUIRE_AUTOCOMPLETE && IsTextInput(input_element) && 493 !input_element->autoComplete()) 494 continue; 495 496 if (requirements & REQUIRE_ENABLED && !control_element->isEnabledFormControl()) 497 continue; 498 499 // Create a new FormField, fill it out and map it to the field's name. 500 FormField* field = new FormField; 501 HTMLFormControlElementToFormField(control_element, extract_mask, field); 502 form_fields.push_back(field); 503 // TODO: A label element is mapped to a form control element's id. 504 // field->name() will contain the id only if the name does not exist. Add 505 // an id() method to HTMLFormControlElement and use that here. 506 name_map[field->name] = field; 507 fields_extracted[i] = true; 508 } 509 510 // Don't extract field labels if we have no fields. 511 if (form_fields.empty()) 512 return false; 513 514 // Loop through the label elements inside the form element. For each label 515 // element, get the corresponding form control element, use the form control 516 // element's name as a key into the <name, FormField> map to find the 517 // previously created FormField and set the FormField's label to the 518 // label.firstChild().nodeValue() of the label element. 519 RefPtr<WebCore::NodeList> labels = element->getElementsByTagName("label"); 520 for (unsigned i = 0; i < labels->length(); ++i) { 521 HTMLLabelElement* label = static_cast<WebCore::HTMLLabelElement*>(labels->item(i)); 522 HTMLFormControlElement* field_element = label->control(); 523 if (!field_element || field_element->type() == "hidden") 524 continue; 525 526 std::map<string16, FormField*>::iterator iter = 527 name_map.find(nameForAutofill(*field_element)); 528 // Concatenate labels because some sites might have multiple label 529 // candidates. 530 if (iter != name_map.end()) 531 iter->second->label += FindChildText(label); 532 } 533 534 // Loop through the form control elements, extracting the label text from the 535 // DOM. We use the |fields_extracted| vector to make sure we assign the 536 // extracted label to the correct field, as it's possible |form_fields| will 537 // not contain all of the elements in |control_elements|. 538 for (size_t i = 0, field_idx = 0; i < control_elements.size() && field_idx < form_fields.size(); ++i) { 539 // This field didn't meet the requirements, so don't try to find a label for 540 // it. 541 if (!fields_extracted[i]) 542 continue; 543 544 if (!control_elements[i]->isFormControlElement()) 545 continue; 546 547 const HTMLFormControlElement* control_element = static_cast<HTMLFormControlElement*>(control_elements[i]); 548 if (form_fields[field_idx]->label.empty()) 549 form_fields[field_idx]->label = InferLabelForElement(*control_element); 550 551 ++field_idx; 552 553 } 554 // Copy the created FormFields into the resulting FormData object. 555 for (ScopedVector<FormField>::const_iterator iter = form_fields.begin(); iter != form_fields.end(); ++iter) 556 form->fields.push_back(**iter); 557 558 return true; 559 } 560 561 void FormManager::ExtractForms(Frame* frame) { 562 563 ResetFrame(frame); 564 565 WTF::PassRefPtr<HTMLCollection> web_forms = frame->document()->forms(); 566 567 for (size_t i = 0; i < web_forms->length(); ++i) { 568 // Owned by |form_elements|. 569 FormElement* form_element = new FormElement; 570 HTMLFormElement* html_form_element = static_cast<HTMLFormElement*>(web_forms->item(i)); 571 form_element->form_element = html_form_element; 572 573 WTF::Vector<FormAssociatedElement*> control_elements = html_form_element->associatedElements(); 574 for (size_t j = 0; j < control_elements.size(); ++j) { 575 if (!control_elements[j]->isFormControlElement()) 576 continue; 577 578 HTMLFormControlElement* element = static_cast<HTMLFormControlElement*>(control_elements[j]); 579 580 if (!IsAutofillableElement(*element)) 581 continue; 582 583 form_element->control_elements.push_back(element); 584 585 // Save original values of <select> elements so we can restore them 586 // when |ClearFormWithNode()| is invoked. 587 if (IsSelectElement(*element)) { 588 HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element); 589 form_element->control_values.push_back(WTFStringToString16(select_element->value())); 590 } else 591 form_element->control_values.push_back(string16()); 592 } 593 594 form_elements_.push_back(form_element); 595 } 596 } 597 598 void FormManager::GetFormsInFrame(const Frame* frame, RequirementsMask requirements, std::vector<FormData>* forms) { 599 DCHECK(frame); 600 DCHECK(forms); 601 602 size_t num_fields_seen = 0; 603 for (FormElementList::const_iterator form_iter = form_elements_.begin(); form_iter != form_elements_.end(); ++form_iter) { 604 FormElement* form_element = *form_iter; 605 606 if (form_element->form_element->document()->frame() != frame) 607 continue; 608 609 // To avoid overly expensive computation, we impose both a minimum and a 610 // maximum number of allowable fields. 611 if (form_element->control_elements.size() < kRequiredAutofillFields || 612 form_element->control_elements.size() > kMaxParseableFields) 613 continue; 614 615 if (requirements & REQUIRE_AUTOCOMPLETE && !form_element->form_element->autoComplete()) 616 continue; 617 618 FormData form; 619 HTMLFormElementToFormData(form_element->form_element.get(), requirements, EXTRACT_VALUE, &form); 620 621 num_fields_seen += form.fields.size(); 622 if (num_fields_seen > kMaxParseableFields) 623 break; 624 625 if (form.fields.size() >= kRequiredAutofillFields) 626 forms->push_back(form); 627 } 628 } 629 630 bool FormManager::FindFormWithFormControlElement(HTMLFormControlElement* element, RequirementsMask requirements, FormData* form) { 631 DCHECK(form); 632 633 const Frame* frame = element->document()->frame(); 634 if (!frame) 635 return false; 636 637 for (FormElementList::const_iterator iter = form_elements_.begin(); iter != form_elements_.end(); ++iter) { 638 const FormElement* form_element = *iter; 639 640 if (form_element->form_element->document()->frame() != frame) 641 continue; 642 643 for (std::vector<RefPtr<HTMLFormControlElement> >::const_iterator iter = form_element->control_elements.begin(); iter != form_element->control_elements.end(); ++iter) { 644 HTMLFormControlElement* candidate = iter->get(); 645 if (nameForAutofill(*candidate) == nameForAutofill(*element)) { 646 ExtractMask extract_mask = static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); 647 return HTMLFormElementToFormData(form_element->form_element.get(), requirements, extract_mask, form); 648 } 649 } 650 } 651 return false; 652 } 653 654 bool FormManager::FillForm(const FormData& form, Node* node) { 655 FormElement* form_element = NULL; 656 if (!FindCachedFormElement(form, &form_element)) 657 return false; 658 659 RequirementsMask requirements = static_cast<RequirementsMask>(REQUIRE_AUTOCOMPLETE | REQUIRE_ENABLED | REQUIRE_EMPTY); 660 ForEachMatchingFormField(form_element, node, requirements, form, NewCallback(this, &FormManager::FillFormField)); 661 662 return true; 663 } 664 665 bool FormManager::PreviewForm(const FormData& form, Node* node) { 666 FormElement* form_element = NULL; 667 if (!FindCachedFormElement(form, &form_element)) 668 return false; 669 670 RequirementsMask requirements = static_cast<RequirementsMask>(REQUIRE_AUTOCOMPLETE | REQUIRE_ENABLED | REQUIRE_EMPTY); 671 ForEachMatchingFormField(form_element, node, requirements, form, NewCallback(this, &FormManager::PreviewFormField)); 672 673 return true; 674 } 675 676 bool FormManager::ClearFormWithNode(Node* node) { 677 FormElement* form_element = NULL; 678 if (!FindCachedFormElementWithNode(node, &form_element)) 679 return false; 680 681 for (size_t i = 0; i < form_element->control_elements.size(); ++i) { 682 HTMLFormControlElement* element = form_element->control_elements[i].get(); 683 HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*element); 684 if (IsTextInput(input_element)) { 685 686 // We don't modify the value of disabled fields. 687 if (!input_element->isEnabledFormControl()) 688 continue; 689 690 input_element->setValue(""); 691 input_element->setAutofilled(false); 692 // Clearing the value in the focused node (above) can cause selection 693 // to be lost. We force selection range to restore the text cursor. 694 if (node == input_element) { 695 int length = input_element->value().length(); 696 input_element->setSelectionRange(length, length); 697 } 698 } else { 699 DCHECK(IsSelectElement(*element)); 700 HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element); 701 if (WTFStringToString16(select_element->value()) != form_element->control_values[i]) { 702 select_element->setValue(form_element->control_values[i].c_str()); 703 select_element->dispatchFormControlChangeEvent(); 704 } 705 } 706 } 707 708 return true; 709 } 710 711 bool FormManager::ClearPreviewedFormWithNode(Node* node, bool was_autofilled) { 712 FormElement* form_element = NULL; 713 if (!FindCachedFormElementWithNode(node, &form_element)) 714 return false; 715 716 for (size_t i = 0; i < form_element->control_elements.size(); ++i) { 717 HTMLFormControlElement* element = form_element->control_elements[i].get(); 718 HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*element); 719 720 // Only input elements can be previewed. 721 if (!IsTextInput(input_element)) 722 continue; 723 724 // If the input element has not been auto-filled, FormManager has not 725 // previewed this field, so we have nothing to reset. 726 if (!input_element->isAutofilled()) 727 continue; 728 729 // There might be unrelated elements in this form which have already been 730 // auto-filled. For example, the user might have already filled the address 731 // part of a form and now be dealing with the credit card section. We only 732 // want to reset the auto-filled status for fields that were previewed. 733 if (input_element->suggestedValue().isEmpty()) 734 continue; 735 736 // Clear the suggested value. For the initiating node, also restore the 737 // original value. 738 input_element->setSuggestedValue(""); 739 bool is_initiating_node = (node == input_element); 740 if (is_initiating_node) { 741 input_element->setAutofilled(was_autofilled); 742 } else { 743 input_element->setAutofilled(false); 744 } 745 746 // Clearing the suggested value in the focused node (above) can cause 747 // selection to be lost. We force selection range to restore the text 748 // cursor. 749 if (is_initiating_node) { 750 int length = input_element->value().length(); 751 input_element->setSelectionRange(length, length); 752 } 753 } 754 755 return true; 756 } 757 758 void FormManager::Reset() { 759 form_elements_.reset(); 760 } 761 762 void FormManager::ResetFrame(const Frame* frame) { 763 FormElementList::iterator iter = form_elements_.begin(); 764 while (iter != form_elements_.end()) { 765 if ((*iter)->form_element->document()->frame() == frame) 766 iter = form_elements_.erase(iter); 767 else 768 ++iter; 769 } 770 } 771 772 bool FormManager::FormWithNodeIsAutofilled(Node* node) { 773 FormElement* form_element = NULL; 774 if (!FindCachedFormElementWithNode(node, &form_element)) 775 return false; 776 777 for (size_t i = 0; i < form_element->control_elements.size(); ++i) { 778 HTMLFormControlElement* element = form_element->control_elements[i].get(); 779 HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*element); 780 if (!IsTextInput(input_element)) 781 continue; 782 783 if (input_element->isAutofilled()) 784 return true; 785 } 786 787 return false; 788 } 789 790 bool FormManager::FindCachedFormElementWithNode(Node* node, FormElement** form_element) { 791 for (FormElementList::const_iterator form_iter = form_elements_.begin(); form_iter != form_elements_.end(); ++form_iter) { 792 for (std::vector<RefPtr<HTMLFormControlElement> >::const_iterator iter = (*form_iter)->control_elements.begin(); iter != (*form_iter)->control_elements.end(); ++iter) { 793 if (iter->get() == node) { 794 *form_element = *form_iter; 795 return true; 796 } 797 } 798 } 799 800 return false; 801 } 802 803 bool FormManager::FindCachedFormElement(const FormData& form, FormElement** form_element) { 804 for (FormElementList::iterator form_iter = form_elements_.begin(); form_iter != form_elements_.end(); ++form_iter) { 805 // TODO: matching on form name here which is not guaranteed to 806 // be unique for the page, nor is it guaranteed to be non-empty. Need to 807 // find a way to uniquely identify the form cross-process. For now we'll 808 // check form name and form action for identity. 809 // http://crbug.com/37990 test file sample8.html. 810 // Also note that WebString() == WebString(string16()) does not evaluate to 811 // |true| -- WebKit distinguisges between a "null" string (lhs) and an 812 // "empty" string (rhs). We don't want that distinction, so forcing to 813 // string16. 814 string16 element_name = GetFormIdentifier(*(*form_iter)->form_element); 815 GURL action(WTFStringToString16((*form_iter)->form_element->document()->completeURL((*form_iter)->form_element->action()).string())); 816 if (element_name == form.name && action == form.action) { 817 *form_element = *form_iter; 818 return true; 819 } 820 } 821 822 return false; 823 } 824 825 826 void FormManager::ForEachMatchingFormField(FormElement* form, Node* node, RequirementsMask requirements, const FormData& data, Callback* callback) { 827 // It's possible that the site has injected fields into the form after the 828 // page has loaded, so we can't assert that the size of the cached control 829 // elements is equal to the size of the fields in |form|. Fortunately, the 830 // one case in the wild where this happens, paypal.com signup form, the fields 831 // are appended to the end of the form and are not visible. 832 for (size_t i = 0, j = 0; i < form->control_elements.size() && j < data.fields.size(); ++i) { 833 HTMLFormControlElement* element = form->control_elements[i].get(); 834 string16 element_name = nameForAutofill(*element); 835 836 // Search forward in the |form| for a corresponding field. 837 size_t k = j; 838 while (k < data.fields.size() && element_name != data.fields[k].name) 839 k++; 840 841 if (k >= data.fields.size()) 842 continue; 843 844 DCHECK_EQ(data.fields[k].name, element_name); 845 846 bool is_initiating_node = false; 847 848 HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*element); 849 if (IsTextInput(input_element)) { 850 // TODO: WebKit currently doesn't handle the autocomplete 851 // attribute for select control elements, but it probably should. 852 if (!input_element->autoComplete()) 853 continue; 854 855 is_initiating_node = (input_element == node); 856 857 // Only autofill empty fields and the firls that initiated the filling, 858 // i.e. the field the user is currently editing and interacting with. 859 if (!is_initiating_node && !input_element->value().isEmpty()) 860 continue; 861 } 862 863 if (!element->isEnabledFormControl() || element->isReadOnlyFormControl() || !element->isFocusable()) 864 continue; 865 866 callback->Run(element, &data.fields[k], is_initiating_node); 867 868 // We found a matching form field so move on to the next. 869 ++j; 870 } 871 872 delete callback; 873 } 874 875 void FormManager::FillFormField(HTMLFormControlElement* field, const FormField* data, bool is_initiating_node) { 876 // Nothing to fill. 877 if (data->value.empty()) 878 return; 879 880 HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*field); 881 882 if (IsTextInput(input_element)) { 883 // If the maxlength attribute contains a negative value, maxLength() 884 // returns the default maxlength value. 885 input_element->setValue(data->value.substr(0, input_element->maxLength()).c_str(), true); 886 input_element->setAutofilled(true); 887 if (is_initiating_node) { 888 int length = input_element->value().length(); 889 input_element->setSelectionRange(length, length); 890 } 891 } else { 892 DCHECK(IsSelectElement(*field)); 893 HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(field); 894 if (WTFStringToString16(select_element->value()) != data->value) { 895 select_element->setValue(data->value.c_str()); 896 select_element->dispatchFormControlChangeEvent(); 897 } 898 } 899 } 900 901 void FormManager::PreviewFormField(HTMLFormControlElement* field, const FormField* data, bool is_initiating_node) { 902 // Nothing to preview. 903 if (data->value.empty()) 904 return; 905 906 // Only preview input fields. 907 HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*field); 908 if (!IsTextInput(input_element)) 909 return; 910 911 // If the maxlength attribute contains a negative value, maxLength() 912 // returns the default maxlength value. 913 input_element->setSuggestedValue(data->value.substr(0, input_element->maxLength()).c_str()); 914 input_element->setAutofilled(true); 915 if (is_initiating_node) { 916 // Select the part of the text that the user didn't type. 917 input_element->setSelectionRange(input_element->value().length(), input_element->suggestedValue().length()); 918 } 919 } 920 921 } 922