| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Installs Autofill management functions on the |__gCrWeb| object. | 5 // Installs Autofill management functions on the |__gCrWeb| object. |
| 6 // | 6 // |
| 7 // It scans the DOM, extracting and storing forms and returns a JSON string | 7 // It scans the DOM, extracting and storing forms and returns a JSON string |
| 8 // representing an array of objects, each of which represents an Autofill form | 8 // representing an array of objects, each of which represents an Autofill form |
| 9 // with information about a form to be filled and/or submitted and it can be | 9 // with information about a form to be filled and/or submitted and it can be |
| 10 // translated to struct FormData | 10 // translated to struct FormData |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 * Google code project settings. | 64 * Google code project settings. |
| 65 * | 65 * |
| 66 * This variable is from | 66 * This variable is from |
| 67 * chromium/src/components/autofill/content/renderer/form_autofill_util.h | 67 * chromium/src/components/autofill/content/renderer/form_autofill_util.h |
| 68 * | 68 * |
| 69 * @const {number} | 69 * @const {number} |
| 70 */ | 70 */ |
| 71 __gCrWeb.autofill.MAX_PARSEABLE_FIELDS = 100; | 71 __gCrWeb.autofill.MAX_PARSEABLE_FIELDS = 100; |
| 72 | 72 |
| 73 /** | 73 /** |
| 74 * A bit field mask for form or form element requirements for requirement | |
| 75 * none. | |
| 76 * | |
| 77 * This variable is from enum RequirementsMask in | |
| 78 * chromium/src/components/autofill/content/renderer/form_autofill_util.h | |
| 79 * | |
| 80 * @const {number} | |
| 81 */ | |
| 82 __gCrWeb.autofill.REQUIREMENTS_MASK_NONE = 0; | |
| 83 | |
| 84 /** | |
| 85 * A bit field mask for form or form element requirements for requirement | |
| 86 * autocomplete != off. | |
| 87 * | |
| 88 * This variable is from enum RequirementsMask in | |
| 89 * chromium/src/components/autofill/content/renderer/form_autofill_util.h | |
| 90 * | |
| 91 * @const {number} | |
| 92 */ | |
| 93 __gCrWeb.autofill.REQUIREMENTS_MASK_REQUIRE_AUTOCOMPLETE = 1; | |
| 94 | |
| 95 /** | |
| 96 * A bit field mask to extract data from WebFormControlElement for | 74 * A bit field mask to extract data from WebFormControlElement for |
| 97 * extracting none value. | 75 * extracting none value. |
| 98 * | 76 * |
| 99 * This variable is from enum ExtractMask in | 77 * This variable is from enum ExtractMask in |
| 100 * chromium/src/components/autofill/content/renderer/form_autofill_util.h | 78 * chromium/src/components/autofill/content/renderer/form_autofill_util.h |
| 101 * | 79 * |
| 102 * @const {number} | 80 * @const {number} |
| 103 */ | 81 */ |
| 104 __gCrWeb.autofill.EXTRACT_MASK_NONE = 0; | 82 __gCrWeb.autofill.EXTRACT_MASK_NONE = 0; |
| 105 | 83 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 __gCrWeb.autofill.lastActiveElement = null; | 131 __gCrWeb.autofill.lastActiveElement = null; |
| 154 | 132 |
| 155 /** | 133 /** |
| 156 * Whether CSS for autofilled elements has been injected into the page. | 134 * Whether CSS for autofilled elements has been injected into the page. |
| 157 * | 135 * |
| 158 * @type {boolean} | 136 * @type {boolean} |
| 159 */ | 137 */ |
| 160 __gCrWeb.autofill.styleInjected = false; | 138 __gCrWeb.autofill.styleInjected = false; |
| 161 | 139 |
| 162 /** | 140 /** |
| 163 * Extracts fields from |controlElements| with |requirements| and |extractMask| | 141 * Extracts fields from |controlElements| with |extractMask| to |formFields|. |
| 164 * to |formFields|. The extracted fields are also placed in |elementArray|. | 142 * The extracted fields are also placed in |elementArray|. |
| 165 * | 143 * |
| 166 * It is based on the logic in | 144 * It is based on the logic in |
| 167 * bool ExtractFieldsFromControlElements( | 145 * bool ExtractFieldsFromControlElements( |
| 168 * const WebVector<WebFormControlElement>& control_elements, | 146 * const WebVector<WebFormControlElement>& control_elements, |
| 169 * RequirementsMask requirements, | |
| 170 * ExtractMask extract_mask, | 147 * ExtractMask extract_mask, |
| 171 * ScopedVector<FormFieldData>* form_fields, | 148 * ScopedVector<FormFieldData>* form_fields, |
| 172 * std::vector<bool>* fields_extracted, | 149 * std::vector<bool>* fields_extracted, |
| 173 * std::map<WebFormControlElement, FormFieldData*>* element_map) | 150 * std::map<WebFormControlElement, FormFieldData*>* element_map) |
| 174 * in chromium/src/components/autofill/content/renderer/form_autofill_util.cc | 151 * in chromium/src/components/autofill/content/renderer/form_autofill_util.cc |
| 175 * | 152 * |
| 176 * TODO(thestig): Get rid of |requirements| to match the C++ version. | |
| 177 * TODO(thestig): Make |element_map| a Map when Chrome makes iOS 8 and Safari 8 | 153 * TODO(thestig): Make |element_map| a Map when Chrome makes iOS 8 and Safari 8 |
| 178 * part of the minimal requirements. | 154 * part of the minimal requirements. |
| 179 * | 155 * |
| 180 * @param {Array<FormControlElement>} controlElements The control elements that | 156 * @param {Array<FormControlElement>} controlElements The control elements that |
| 181 * will be processed. | 157 * will be processed. |
| 182 * @param {number} requirements The requirement on control element | |
| 183 * autocompletion. | |
| 184 * @param {number} extractMask Mask controls what data is extracted from | 158 * @param {number} extractMask Mask controls what data is extracted from |
| 185 * controlElements. | 159 * controlElements. |
| 186 * @param {Array<AutofillFormFieldData>} formFields The extracted form fields. | 160 * @param {Array<AutofillFormFieldData>} formFields The extracted form fields. |
| 187 * @param {Array<boolean>} fieldsExtracted Indicates whether the fields were | 161 * @param {Array<boolean>} fieldsExtracted Indicates whether the fields were |
| 188 * extracted. | 162 * extracted. |
| 189 * @param {Array<?AutofillFormFieldData>} elementArray The extracted form | 163 * @param {Array<?AutofillFormFieldData>} elementArray The extracted form |
| 190 * fields or null if a particular control has no corresponding field. | 164 * fields or null if a particular control has no corresponding field. |
| 191 * @return {boolean} Whether there are fields and not too many fields in the | 165 * @return {boolean} Whether there are fields and not too many fields in the |
| 192 * form. | 166 * form. |
| 193 */ | 167 */ |
| 194 function extractFieldsFromControlElements_(controlElements, requirements, | 168 function extractFieldsFromControlElements_(controlElements, extractMask, |
| 195 extractMask, formFields, fieldsExtracted, elementArray) { | 169 formFields, fieldsExtracted, elementArray) { |
| 196 for (var i = 0; i < controlElements.length; ++i) { | 170 for (var i = 0; i < controlElements.length; ++i) { |
| 197 fieldsExtracted[i] = false; | 171 fieldsExtracted[i] = false; |
| 198 elementArray[i] = null; | 172 elementArray[i] = null; |
| 199 | 173 |
| 200 /** @type {FormControlElement} */ | 174 /** @type {FormControlElement} */ |
| 201 var controlElement = controlElements[i]; | 175 var controlElement = controlElements[i]; |
| 202 if (!__gCrWeb.autofill.isAutofillableElement(controlElement)) { | 176 if (!__gCrWeb.autofill.isAutofillableElement(controlElement)) { |
| 203 continue; | 177 continue; |
| 204 } | 178 } |
| 205 | 179 |
| 206 if ((requirements & | |
| 207 __gCrWeb.autofill.REQUIREMENTS_MASK_REQUIRE_AUTOCOMPLETE) && | |
| 208 __gCrWeb.autofill.isAutofillableInputElement(controlElement) && | |
| 209 !__gCrWeb.autofill.satisfiesRequireAutocomplete( | |
| 210 controlElement, false)) { | |
| 211 continue; | |
| 212 } | |
| 213 | |
| 214 // Create a new AutofillFormFieldData, fill it out and map it to the | 180 // Create a new AutofillFormFieldData, fill it out and map it to the |
| 215 // field's name. | 181 // field's name. |
| 216 var formField = new __gCrWeb['common'].JSONSafeObject; | 182 var formField = new __gCrWeb['common'].JSONSafeObject; |
| 217 __gCrWeb.autofill.webFormControlElementToFormField( | 183 __gCrWeb.autofill.webFormControlElementToFormField( |
| 218 controlElement, extractMask, formField); | 184 controlElement, extractMask, formField); |
| 219 formFields.push(formField); | 185 formFields.push(formField); |
| 220 elementArray[i] = formField; | 186 elementArray[i] = formField; |
| 221 fieldsExtracted[i] = true; | 187 fieldsExtracted[i] = true; |
| 222 | 188 |
| 223 // To avoid overly expensive computation, we impose a maximum number of | 189 // To avoid overly expensive computation, we impose a maximum number of |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 * 1) |formElement|, |formControlElement| and an empty |fieldsets|. | 304 * 1) |formElement|, |formControlElement| and an empty |fieldsets|. |
| 339 * or | 305 * or |
| 340 * 2) a non-empty |fieldsets|. | 306 * 2) a non-empty |fieldsets|. |
| 341 * | 307 * |
| 342 * It is based on the logic in | 308 * It is based on the logic in |
| 343 * bool FormOrFieldsetsToFormData( | 309 * bool FormOrFieldsetsToFormData( |
| 344 * const blink::WebFormElement* form_element, | 310 * const blink::WebFormElement* form_element, |
| 345 * const blink::WebFormControlElement* form_control_element, | 311 * const blink::WebFormControlElement* form_control_element, |
| 346 * const std::vector<blink::WebElement>& fieldsets, | 312 * const std::vector<blink::WebElement>& fieldsets, |
| 347 * const WebVector<WebFormControlElement>& control_elements, | 313 * const WebVector<WebFormControlElement>& control_elements, |
| 348 * RequirementsMask requirements, | |
| 349 * ExtractMask extract_mask, | 314 * ExtractMask extract_mask, |
| 350 * FormData* form, | 315 * FormData* form, |
| 351 * FormFieldData* field) | 316 * FormFieldData* field) |
| 352 * in chromium/src/components/autofill/content/renderer/form_autofill_util.cc | 317 * in chromium/src/components/autofill/content/renderer/form_autofill_util.cc |
| 353 * | 318 * |
| 354 * @param {HTMLFormElement} formElement The form element that will be processed. | 319 * @param {HTMLFormElement} formElement The form element that will be processed. |
| 355 * @param {FormControlElement} formControlElement A control element in | 320 * @param {FormControlElement} formControlElement A control element in |
| 356 * formElment, the FormField of which will be returned in field. | 321 * formElment, the FormField of which will be returned in field. |
| 357 * @param {Array<Element>} fieldsets The fieldsets to look through if | 322 * @param {Array<Element>} fieldsets The fieldsets to look through if |
| 358 * formElement and formControlElement are not specified. | 323 * formElement and formControlElement are not specified. |
| 359 * @param {Array<FormControlElement>} controlElements The control elements that | 324 * @param {Array<FormControlElement>} controlElements The control elements that |
| 360 * will be processed. | 325 * will be processed. |
| 361 * @param {number} requirements The requirement on formElement autocompletion. | |
| 362 * @param {number} extractMask Mask controls what data is extracted from | 326 * @param {number} extractMask Mask controls what data is extracted from |
| 363 * formElement. | 327 * formElement. |
| 364 * @param {AutofillFormData} form Form to fill in the AutofillFormData | 328 * @param {AutofillFormData} form Form to fill in the AutofillFormData |
| 365 * information of formElement. | 329 * information of formElement. |
| 366 * @param {AutofillFormFieldData|null} field Field to fill in the form field | 330 * @param {AutofillFormFieldData|null} field Field to fill in the form field |
| 367 * information of formControlElement. | 331 * information of formControlElement. |
| 368 * @return {boolean} Whether there are fields and not too many fields in the | 332 * @return {boolean} Whether there are fields and not too many fields in the |
| 369 * form. | 333 * form. |
| 370 */ | 334 */ |
| 371 function formOrFieldsetsToFormData_(formElement, formControlElement, | 335 function formOrFieldsetsToFormData_(formElement, formControlElement, |
| 372 fieldsets, controlElements, requirements, extractMask, form, field) { | 336 fieldsets, controlElements, extractMask, form, field) { |
| 373 // This should be a map from a control element to the AutofillFormFieldData. | 337 // This should be a map from a control element to the AutofillFormFieldData. |
| 374 // However, without Map support, it's just an Array of AutofillFormFieldData. | 338 // However, without Map support, it's just an Array of AutofillFormFieldData. |
| 375 var elementArray = []; | 339 var elementArray = []; |
| 376 | 340 |
| 377 // The extracted FormFields. | 341 // The extracted FormFields. |
| 378 var formFields = []; | 342 var formFields = []; |
| 379 | 343 |
| 380 // A vector of bools that indicate whether each element in |controlElements| | 344 // A vector of bools that indicate whether each element in |controlElements| |
| 381 // meets the requirements and thus will be in the resulting |form|. | 345 // meets the requirements and thus will be in the resulting |form|. |
| 382 var fieldsExtracted = []; | 346 var fieldsExtracted = []; |
| 383 | 347 |
| 384 if (!extractFieldsFromControlElements_(controlElements, requirements, | 348 if (!extractFieldsFromControlElements_(controlElements, extractMask, |
| 385 extractMask, formFields, | 349 formFields, fieldsExtracted, |
| 386 fieldsExtracted, elementArray)) { | 350 elementArray)) { |
| 387 return false; | 351 return false; |
| 388 } | 352 } |
| 389 | 353 |
| 390 if (formElement) { | 354 if (formElement) { |
| 391 // Loop through the label elements inside the form element. For each label | 355 // Loop through the label elements inside the form element. For each label |
| 392 // element, get the corresponding form control element, use the form control | 356 // element, get the corresponding form control element, use the form control |
| 393 // element along with |controlElements| and |elementArray| to find the | 357 // element along with |controlElements| and |elementArray| to find the |
| 394 // previously created AutofillFormFieldData and set the | 358 // previously created AutofillFormFieldData and set the |
| 395 // AutofillFormFieldData's label. | 359 // AutofillFormFieldData's label. |
| 396 var labels = formElement.getElementsByTagName('label'); | 360 var labels = formElement.getElementsByTagName('label'); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 } | 396 } |
| 433 | 397 |
| 434 /** | 398 /** |
| 435 * Scans DOM and returns a JSON string representation of forms and form | 399 * Scans DOM and returns a JSON string representation of forms and form |
| 436 * extraction results. | 400 * extraction results. |
| 437 * | 401 * |
| 438 * TODO(thestig): Merge with extractNewForms()? | 402 * TODO(thestig): Merge with extractNewForms()? |
| 439 * | 403 * |
| 440 * @param {number} requiredFields The minimum number of fields forms must have | 404 * @param {number} requiredFields The minimum number of fields forms must have |
| 441 * to be extracted. | 405 * to be extracted. |
| 442 * @param {number} requirements The requirements mask for forms, e.g. | |
| 443 * autocomplete attribute state. | |
| 444 * @return {string} A JSON encoded object with object['forms'] containing the | 406 * @return {string} A JSON encoded object with object['forms'] containing the |
| 445 * forms data. | 407 * forms data. |
| 446 */ | 408 */ |
| 447 __gCrWeb.autofill['extractForms'] = function(requiredFields, requirements) { | 409 __gCrWeb.autofill['extractForms'] = function(requiredFields) { |
| 448 var forms = []; | 410 var forms = []; |
| 449 // Protect against custom implementation of Array.toJSON in host pages. | 411 // Protect against custom implementation of Array.toJSON in host pages. |
| 450 /** @suppress {checkTypes} */(function() { forms.toJSON = null; })(); | 412 /** @suppress {checkTypes} */(function() { forms.toJSON = null; })(); |
| 451 | 413 |
| 452 // TODO(chenyu): check if any preparation is needed for information such as | 414 // TODO(chenyu): check if any preparation is needed for information such as |
| 453 // user_submitted or the one added in core.js is sufficient. | 415 // user_submitted or the one added in core.js is sufficient. |
| 454 __gCrWeb.autofill.extractNewForms( | 416 __gCrWeb.autofill.extractNewForms( |
| 455 window, | 417 window, |
| 456 requiredFields, | 418 requiredFields, |
| 457 requirements, | |
| 458 forms); | 419 forms); |
| 459 var results = new __gCrWeb.common.JSONSafeObject; | 420 var results = new __gCrWeb.common.JSONSafeObject; |
| 460 results['forms'] = forms; | 421 results['forms'] = forms; |
| 461 return __gCrWeb.stringify(results); | 422 return __gCrWeb.stringify(results); |
| 462 }; | 423 }; |
| 463 | 424 |
| 464 /** | 425 /** |
| 465 * Stores the current active element. This is used to make the element active | 426 * Stores the current active element. This is used to make the element active |
| 466 * again in case the web view loses focus when a dialog is presented over it. | 427 * again in case the web view loses focus when a dialog is presented over it. |
| 467 */ | 428 */ |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 formElement.dispatchEvent(event); | 541 formElement.dispatchEvent(event); |
| 581 }; | 542 }; |
| 582 | 543 |
| 583 /** | 544 /** |
| 584 * See extractFormsAndFormElements below. | 545 * See extractFormsAndFormElements below. |
| 585 * | 546 * |
| 586 * @param {HTMLFrameElement|Window} frame A window or a frame containing forms | 547 * @param {HTMLFrameElement|Window} frame A window or a frame containing forms |
| 587 * from which the data will be extracted. | 548 * from which the data will be extracted. |
| 588 * @param {number} minimumRequiredFields The minimum number of fields a form | 549 * @param {number} minimumRequiredFields The minimum number of fields a form |
| 589 * should contain for autofill. | 550 * should contain for autofill. |
| 590 * @param {number} requirements The requirements mask for forms, e.g. | |
| 591 * autocomplete attribute state. | |
| 592 * @param {Array<AutofillFormData>} forms Forms that will be filled in data of | 551 * @param {Array<AutofillFormData>} forms Forms that will be filled in data of |
| 593 * forms in frame. | 552 * forms in frame. |
| 594 */ | 553 */ |
| 595 __gCrWeb.autofill.extractNewForms = function( | 554 __gCrWeb.autofill.extractNewForms = function( |
| 596 frame, minimumRequiredFields, requirements, forms) { | 555 frame, minimumRequiredFields, forms) { |
| 597 __gCrWeb.autofill.extractFormsAndFormElements( | 556 __gCrWeb.autofill.extractFormsAndFormElements( |
| 598 frame, minimumRequiredFields, requirements, forms); | 557 frame, minimumRequiredFields, forms); |
| 599 } | 558 } |
| 600 | 559 |
| 601 /** | 560 /** |
| 602 * Scans the DOM in |frame| extracting and storing forms. Fills |forms| with | 561 * Scans the DOM in |frame| extracting and storing forms. Fills |forms| with |
| 603 * extracted forms. | 562 * extracted forms. |
| 604 * | 563 * |
| 605 * This method is based on the logic in method | 564 * This method is based on the logic in method |
| 606 * | 565 * |
| 607 * bool FormCache::ExtractNewForms( | 566 * bool FormCache::ExtractNewForms( |
| 608 * const WebFrame& frame, | 567 * const WebFrame& frame, |
| 609 * std::vector<FormData>* forms) | 568 * std::vector<FormData>* forms) |
| 610 * | 569 * |
| 611 * in chromium/src/components/autofill/content/renderer/form_cache.cc. | 570 * in chromium/src/components/autofill/content/renderer/form_cache.cc. |
| 612 * | 571 * |
| 613 * The difference is in this implementation, the cache is not considered. | 572 * The difference is in this implementation, the cache is not considered. |
| 614 * Initial values of select and checkable elements are not recorded at the | 573 * Initial values of select and checkable elements are not recorded at the |
| 615 * moment. | 574 * moment. |
| 616 * | 575 * |
| 617 * This version still takes the minimumRequiredFields and requirements | 576 * This version still takes the minimumRequiredFields parameters. Whereas the |
| 618 * parameters. Whereas the C++ version does not. | 577 * C++ version does not. |
| 619 * | 578 * |
| 620 * TODO(thestig): Update iOS internal callers to use extractNewForms(). Once | 579 * TODO(thestig): Update iOS internal callers to use extractNewForms(). Once |
| 621 * that happens, this can be removed. | 580 * that happens, this can be removed. |
| 622 * | 581 * |
| 623 * @param {HTMLFrameElement|Window} frame A window or a frame containing forms | 582 * @param {HTMLFrameElement|Window} frame A window or a frame containing forms |
| 624 * from which the data will be extracted. | 583 * from which the data will be extracted. |
| 625 * @param {number} minimumRequiredFields The minimum number of fields a form | 584 * @param {number} minimumRequiredFields The minimum number of fields a form |
| 626 * should contain for autofill. | 585 * should contain for autofill. |
| 627 * @param {number} requirements The requirements mask for forms, e.g. | |
| 628 * autocomplete attribute state. | |
| 629 * @param {Array<AutofillFormData>} forms Forms that will be filled in data of | 586 * @param {Array<AutofillFormData>} forms Forms that will be filled in data of |
| 630 * forms in frame. | 587 * forms in frame. |
| 631 * @return {boolean} Whether there are unextracted forms due to | 588 * @return {boolean} Whether there are unextracted forms due to |
| 632 * |minimumRequiredFields| limit. | 589 * |minimumRequiredFields| limit. |
| 633 */ | 590 */ |
| 634 __gCrWeb.autofill.extractFormsAndFormElements = function( | 591 __gCrWeb.autofill.extractFormsAndFormElements = function( |
| 635 frame, minimumRequiredFields, requirements, forms) { | 592 frame, minimumRequiredFields, forms) { |
| 636 if (!frame) { | 593 if (!frame) { |
| 637 return false; | 594 return false; |
| 638 } | 595 } |
| 639 var doc = frame.document; | 596 var doc = frame.document; |
| 640 if (!doc) { | 597 if (!doc) { |
| 641 return false; | 598 return false; |
| 642 } | 599 } |
| 643 | 600 |
| 644 /** @type {HTMLCollection} */ | 601 /** @type {HTMLCollection} */ |
| 645 var webForms = doc.forms; | 602 var webForms = doc.forms; |
| 646 | 603 |
| 647 var numFieldsSeen = 0; | 604 var numFieldsSeen = 0; |
| 648 var hasSkippedForms = false; | 605 var hasSkippedForms = false; |
| 649 for (var formIndex = 0; formIndex < webForms.length; ++formIndex) { | 606 for (var formIndex = 0; formIndex < webForms.length; ++formIndex) { |
| 650 /** @type {HTMLFormElement} */ | 607 /** @type {HTMLFormElement} */ |
| 651 var formElement = webForms[formIndex]; | 608 var formElement = webForms[formIndex]; |
| 652 var controlElements = __gCrWeb.autofill.extractAutofillableElementsInForm( | 609 var controlElements = |
| 653 formElement, requirements); | 610 __gCrWeb.autofill.extractAutofillableElementsInForm(formElement); |
| 654 var numEditableElements = 0; | 611 var numEditableElements = 0; |
| 655 for (var elementIndex = 0; elementIndex < controlElements.length; | 612 for (var elementIndex = 0; elementIndex < controlElements.length; |
| 656 ++elementIndex) { | 613 ++elementIndex) { |
| 657 var element = controlElements[elementIndex]; | 614 var element = controlElements[elementIndex]; |
| 658 if (!__gCrWeb.autofill.isCheckableElement(element)) { | 615 if (!__gCrWeb.autofill.isCheckableElement(element)) { |
| 659 ++numEditableElements; | 616 ++numEditableElements; |
| 660 } | 617 } |
| 661 } | 618 } |
| 662 | 619 |
| 663 // To avoid overly expensive computation, we impose a minimum number of | 620 // To avoid overly expensive computation, we impose a minimum number of |
| 664 // allowable fields. The corresponding maximum number of allowable | 621 // allowable fields. The corresponding maximum number of allowable |
| 665 // fields is imposed by webFormElementToFormData(). | 622 // fields is imposed by webFormElementToFormData(). |
| 666 if (numEditableElements < minimumRequiredFields && | 623 if (numEditableElements < minimumRequiredFields && |
| 667 controlElements.length > 0) { | 624 controlElements.length > 0) { |
| 668 hasSkippedForms = true; | 625 hasSkippedForms = true; |
| 669 continue; | 626 continue; |
| 670 } | 627 } |
| 671 | 628 |
| 672 var extractMask = __gCrWeb.autofill.EXTRACT_MASK_VALUE | | 629 var extractMask = __gCrWeb.autofill.EXTRACT_MASK_VALUE | |
| 673 __gCrWeb.autofill.EXTRACT_MASK_OPTIONS; | 630 __gCrWeb.autofill.EXTRACT_MASK_OPTIONS; |
| 674 var form = new __gCrWeb['common'].JSONSafeObject; | 631 var form = new __gCrWeb['common'].JSONSafeObject; |
| 675 if (!__gCrWeb.autofill.webFormElementToFormData( | 632 if (!__gCrWeb.autofill.webFormElementToFormData( |
| 676 frame, formElement, null, requirements, extractMask, form, | 633 frame, formElement, null, extractMask, form, null /* field */)) { |
| 677 null /* field */)) { | |
| 678 continue; | 634 continue; |
| 679 } | 635 } |
| 680 numFieldsSeen += form['fields'].length; | 636 numFieldsSeen += form['fields'].length; |
| 681 if (numFieldsSeen > __gCrWeb.autofill.MAX_PARSEABLE_FIELDS) { | 637 if (numFieldsSeen > __gCrWeb.autofill.MAX_PARSEABLE_FIELDS) { |
| 682 break; | 638 break; |
| 683 } | 639 } |
| 684 | 640 |
| 685 if (form.fields.length >= minimumRequiredFields) { | 641 if (form.fields.length >= minimumRequiredFields) { |
| 686 forms.push(form); | 642 forms.push(form); |
| 687 } else { | 643 } else { |
| 688 hasSkippedForms = true; | 644 hasSkippedForms = true; |
| 689 } | 645 } |
| 690 } | 646 } |
| 691 | 647 |
| 692 // Recursively invoke for all frames/iframes. | 648 // Recursively invoke for all frames/iframes. |
| 693 var frames = frame.frames; | 649 var frames = frame.frames; |
| 694 for (var i = 0; i < frames.length; i++) { | 650 for (var i = 0; i < frames.length; i++) { |
| 695 var hasSkippedInframe = __gCrWeb.autofill.extractFormsAndFormElements( | 651 var hasSkippedInframe = __gCrWeb.autofill.extractFormsAndFormElements( |
| 696 frames[i], minimumRequiredFields, requirements, forms); | 652 frames[i], minimumRequiredFields, forms); |
| 697 hasSkippedForms = hasSkippedForms || hasSkippedInframe; | 653 hasSkippedForms = hasSkippedForms || hasSkippedInframe; |
| 698 } | 654 } |
| 699 return hasSkippedForms; | 655 return hasSkippedForms; |
| 700 }; | 656 }; |
| 701 | 657 |
| 702 /** | 658 /** |
| 703 * Fills |form| with the form data object corresponding to the |formElement|. | 659 * Fills |form| with the form data object corresponding to the |formElement|. |
| 704 * If |field| is non-NULL, also fills |field| with the FormField object | 660 * If |field| is non-NULL, also fills |field| with the FormField object |
| 705 * corresponding to the |formControlElement|. | 661 * corresponding to the |formControlElement|. |
| 706 * |extract_mask| controls what data is extracted. | 662 * |extract_mask| controls what data is extracted. |
| 707 * Returns true if |form| is filled out; it's possible that the |formElement| | 663 * Returns true if |form| is filled out. Returns false if there are no fields or |
| 708 * won't meet the |requirements|. Also returns false if there are no fields or | |
| 709 * too many fields in the |form|. | 664 * too many fields in the |form|. |
| 710 * | 665 * |
| 711 * It is based on the logic in | 666 * It is based on the logic in |
| 712 * bool WebFormElementToFormData( | 667 * bool WebFormElementToFormData( |
| 713 * const blink::WebFormElement& form_element, | 668 * const blink::WebFormElement& form_element, |
| 714 * const blink::WebFormControlElement& form_control_element, | 669 * const blink::WebFormControlElement& form_control_element, |
| 715 * RequirementsMask requirements, | |
| 716 * ExtractMask extract_mask, | 670 * ExtractMask extract_mask, |
| 717 * FormData* form, | 671 * FormData* form, |
| 718 * FormFieldData* field) | 672 * FormFieldData* field) |
| 719 * in chromium/src/components/autofill/content/renderer/form_autofill_util.cc | 673 * in chromium/src/components/autofill/content/renderer/form_autofill_util.cc |
| 720 * | 674 * |
| 721 * @param {HTMLFrameElement|Window} frame The window or frame where the | 675 * @param {HTMLFrameElement|Window} frame The window or frame where the |
| 722 * formElement is in. | 676 * formElement is in. |
| 723 * @param {HTMLFormElement} formElement The form element that will be processed. | 677 * @param {HTMLFormElement} formElement The form element that will be processed. |
| 724 * @param {FormControlElement} formControlElement A control element in | 678 * @param {FormControlElement} formControlElement A control element in |
| 725 * formElment, the FormField of which will be returned in field. | 679 * formElment, the FormField of which will be returned in field. |
| 726 * @param {number} requirements The requirement on formElement autocompletion. | |
| 727 * @param {number} extractMask Mask controls what data is extracted from | 680 * @param {number} extractMask Mask controls what data is extracted from |
| 728 * formElement. | 681 * formElement. |
| 729 * @param {AutofillFormData} form Form to fill in the AutofillFormData | 682 * @param {AutofillFormData} form Form to fill in the AutofillFormData |
| 730 * information of formElement. | 683 * information of formElement. |
| 731 * @param {AutofillFormFieldData|null} field Field to fill in the form field | 684 * @param {AutofillFormFieldData|null} field Field to fill in the form field |
| 732 * information of formControlElement. | 685 * information of formControlElement. |
| 733 * @return {boolean} Whether there are fields and not too many fields in the | 686 * @return {boolean} Whether there are fields and not too many fields in the |
| 734 * form. | 687 * form. |
| 735 */ | 688 */ |
| 736 __gCrWeb.autofill.webFormElementToFormData = function( | 689 __gCrWeb.autofill.webFormElementToFormData = function( |
| 737 frame, formElement, formControlElement, requirements, extractMask, form, | 690 frame, formElement, formControlElement, extractMask, form, field) { |
| 738 field) { | |
| 739 if (!frame) { | 691 if (!frame) { |
| 740 return false; | 692 return false; |
| 741 } | 693 } |
| 742 | 694 |
| 743 if ((requirements & | |
| 744 __gCrWeb.autofill.REQUIREMENTS_MASK_REQUIRE_AUTOCOMPLETE) && | |
| 745 !__gCrWeb['common'].autoComplete(formElement)) { | |
| 746 return false; | |
| 747 } | |
| 748 | |
| 749 form['name'] = __gCrWeb.common.getFormIdentifier(formElement); | 695 form['name'] = __gCrWeb.common.getFormIdentifier(formElement); |
| 750 var method = formElement.getAttribute('method'); | 696 var method = formElement.getAttribute('method'); |
| 751 if (method) { | 697 if (method) { |
| 752 form['method'] = method; | 698 form['method'] = method; |
| 753 } | 699 } |
| 754 form['origin'] = __gCrWeb.common.removeQueryAndReferenceFromURL( | 700 form['origin'] = __gCrWeb.common.removeQueryAndReferenceFromURL( |
| 755 frame.location.href); | 701 frame.location.href); |
| 756 form['action'] = __gCrWeb.common.absoluteURL( | 702 form['action'] = __gCrWeb.common.absoluteURL( |
| 757 frame.document, | 703 frame.document, |
| 758 formElement.getAttribute('action')); | 704 formElement.getAttribute('action')); |
| 759 // form['userSubmitted'] is filled by native code. See http://crbug.com/231264 | 705 // form['userSubmitted'] is filled by native code. See http://crbug.com/231264 |
| 760 | 706 |
| 761 // Note different from form_autofill_util.cc version of this method, which | 707 // Note different from form_autofill_util.cc version of this method, which |
| 762 // computes |form.action| using document.completeURL(form_element.action()) | 708 // computes |form.action| using document.completeURL(form_element.action()) |
| 763 // and falls back to formElement.action() if the computed action is invalid, | 709 // and falls back to formElement.action() if the computed action is invalid, |
| 764 // here the action returned by |__gCrWeb.common.absoluteURL| is always | 710 // here the action returned by |__gCrWeb.common.absoluteURL| is always |
| 765 // valid, which is computed by creating a <a> element, and we don't check if | 711 // valid, which is computed by creating a <a> element, and we don't check if |
| 766 // the action is valid. | 712 // the action is valid. |
| 767 | 713 |
| 768 var controlElements = __gCrWeb['common'].getFormControlElements(formElement); | 714 var controlElements = __gCrWeb['common'].getFormControlElements(formElement); |
| 769 | 715 |
| 770 return formOrFieldsetsToFormData_(formElement, formControlElement, | 716 return formOrFieldsetsToFormData_(formElement, formControlElement, |
| 771 [] /* fieldsets */, controlElements, requirements, extractMask, form, | 717 [] /* fieldsets */, controlElements, extractMask, form, field); |
| 772 field); | |
| 773 }; | 718 }; |
| 774 | 719 |
| 775 /** | 720 /** |
| 776 * Returns is the tag of an |element| is tag. | 721 * Returns is the tag of an |element| is tag. |
| 777 * | 722 * |
| 778 * It is based on the logic in | 723 * It is based on the logic in |
| 779 * bool HasTagName(const WebNode& node, const blink::WebString& tag) | 724 * bool HasTagName(const WebNode& node, const blink::WebString& tag) |
| 780 * in chromium/src/components/autofill/content/renderer/form_autofill_util.cc. | 725 * in chromium/src/components/autofill/content/renderer/form_autofill_util.cc. |
| 781 * | 726 * |
| 782 * @param {Node} node Node to examine. | 727 * @param {Node} node Node to examine. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 799 * @return {boolean} Whether element is one of the element types that can be | 744 * @return {boolean} Whether element is one of the element types that can be |
| 800 * autofilled. | 745 * autofilled. |
| 801 */ | 746 */ |
| 802 __gCrWeb.autofill.isAutofillableElement = function(element) { | 747 __gCrWeb.autofill.isAutofillableElement = function(element) { |
| 803 return __gCrWeb.autofill.isAutofillableInputElement(element) || | 748 return __gCrWeb.autofill.isAutofillableInputElement(element) || |
| 804 __gCrWeb.autofill.isSelectElement(element) || | 749 __gCrWeb.autofill.isSelectElement(element) || |
| 805 __gCrWeb.autofill.isTextAreaElement(element); | 750 __gCrWeb.autofill.isTextAreaElement(element); |
| 806 }; | 751 }; |
| 807 | 752 |
| 808 /** | 753 /** |
| 809 * Check whether the given field satisfies the | |
| 810 * __gCrWeb.autofill.REQUIREMENTS_MASK_REQUIRE_AUTOCOMPLETE requirement. When | |
| 811 * Autocheckout is enabled, all fields are considered to satisfy this | |
| 812 * requirement. | |
| 813 * | |
| 814 * It is based on the logic in | |
| 815 * bool SatisfiesRequireAutocomplete(const WebInputElement& input_element) | |
| 816 * in chromium/src/components/autofill/content/renderer/form_autofill_util.cc. | |
| 817 * | |
| 818 * @param {Element} element The element to be examined. | |
| 819 * @param {boolean} isExperimentalFormFillingEnabled Boolean from | |
| 820 * switches::kEnableExperimentalFormFilling. | |
| 821 * @return {boolean} Whether the inputElement satisfies the requirement. | |
| 822 */ | |
| 823 __gCrWeb.autofill.satisfiesRequireAutocomplete = function( | |
| 824 element, isExperimentalFormFillingEnabled) { | |
| 825 return __gCrWeb.common.autoComplete(element) || | |
| 826 isExperimentalFormFillingEnabled; | |
| 827 }; | |
| 828 | |
| 829 /** | |
| 830 * Trims whitespace from the start of the input string. | 754 * Trims whitespace from the start of the input string. |
| 831 * Simplified version of string_util::TrimWhitespace. | 755 * Simplified version of string_util::TrimWhitespace. |
| 832 * @param {string} input String to trim. | 756 * @param {string} input String to trim. |
| 833 * @return {string} The |input| string without leading whitespace. | 757 * @return {string} The |input| string without leading whitespace. |
| 834 */ | 758 */ |
| 835 __gCrWeb.autofill.trimWhitespaceLeading = function(input) { | 759 __gCrWeb.autofill.trimWhitespaceLeading = function(input) { |
| 836 return input.replace(/^\s+/gm, ''); | 760 return input.replace(/^\s+/gm, ''); |
| 837 }; | 761 }; |
| 838 | 762 |
| 839 /** | 763 /** |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1570 __gCrWeb.autofill.value = function(element) { | 1494 __gCrWeb.autofill.value = function(element) { |
| 1571 return (element.value || '').replace(/[\n\t]/gm, ''); | 1495 return (element.value || '').replace(/[\n\t]/gm, ''); |
| 1572 }; | 1496 }; |
| 1573 | 1497 |
| 1574 /** | 1498 /** |
| 1575 * Returns the auto-fillable form control elements in |formElement|. | 1499 * Returns the auto-fillable form control elements in |formElement|. |
| 1576 * | 1500 * |
| 1577 * It is based on the logic in: | 1501 * It is based on the logic in: |
| 1578 * std::vector<blink::WebFormControlElement> | 1502 * std::vector<blink::WebFormControlElement> |
| 1579 * ExtractAutofillableElementsFromSet( | 1503 * ExtractAutofillableElementsFromSet( |
| 1580 * const WebVector<WebFormControlElement>& control_elements, | 1504 * const WebVector<WebFormControlElement>& control_elements); |
| 1581 * RequirementsMask requirements); | |
| 1582 * in chromium/src/components/autofill/content/renderer/form_autofill_util.h. | 1505 * in chromium/src/components/autofill/content/renderer/form_autofill_util.h. |
| 1583 * | 1506 * |
| 1584 * @param {Array<FormControlElement>} controlElements Set of control elements. | 1507 * @param {Array<FormControlElement>} controlElements Set of control elements. |
| 1585 * @param {number} requirementsMask A mask on the requirement. | |
| 1586 * @return {Array<FormControlElement>} The array of autofillable elements. | 1508 * @return {Array<FormControlElement>} The array of autofillable elements. |
| 1587 */ | 1509 */ |
| 1588 __gCrWeb.autofill.extractAutofillableElementsFromSet = function( | 1510 __gCrWeb.autofill.extractAutofillableElementsFromSet = |
| 1589 controlElements, requirementsMask) { | 1511 function(controlElements) { |
| 1590 var autofillableElements = []; | 1512 var autofillableElements = []; |
| 1591 for (var i = 0; i < controlElements.length; ++i) { | 1513 for (var i = 0; i < controlElements.length; ++i) { |
| 1592 var element = controlElements[i]; | 1514 var element = controlElements[i]; |
| 1593 if (!__gCrWeb.autofill.isAutofillableElement(element)) { | 1515 if (!__gCrWeb.autofill.isAutofillableElement(element)) { |
| 1594 continue; | 1516 continue; |
| 1595 } | 1517 } |
| 1596 if (requirementsMask & | |
| 1597 __gCrWeb.autofill.REQUIREMENTS_MASK_REQUIRE_AUTOCOMPLETE) { | |
| 1598 // Different from method void ExtractAutofillableElements() in | |
| 1599 // chromium/src/components/autofill/content/renderer/form_autofill_util.h, | |
| 1600 // where satisfiesRequireAutocomplete() check is only applied on input | |
| 1601 // controls, here satisfiesRequireAutocomplete() check is also applied on | |
| 1602 // select control element. This is based on the TODO in that file saying | |
| 1603 // "WebKit currently doesn't handle the autocomplete attribute for select | |
| 1604 // control elements, but it probably should." | |
| 1605 if (!__gCrWeb.autofill.satisfiesRequireAutocomplete(element, false)) { | |
| 1606 continue; | |
| 1607 } | |
| 1608 } | |
| 1609 autofillableElements.push(element); | 1518 autofillableElements.push(element); |
| 1610 } | 1519 } |
| 1611 return autofillableElements; | 1520 return autofillableElements; |
| 1612 }; | 1521 }; |
| 1613 | 1522 |
| 1614 /** | 1523 /** |
| 1615 * Returns all the auto-fillable form control elements in |formElement|. | 1524 * Returns all the auto-fillable form control elements in |formElement|. |
| 1616 * | 1525 * |
| 1617 * It is based on the logic in | 1526 * It is based on the logic in |
| 1618 * void ExtractAutofillableElementsInForm( | 1527 * void ExtractAutofillableElementsInForm( |
| 1619 * const blink::WebFormElement& form_element, | 1528 * const blink::WebFormElement& form_element); |
| 1620 * RequirementsMask requirements); | |
| 1621 * in chromium/src/components/autofill/content/renderer/form_autofill_util.h. | 1529 * in chromium/src/components/autofill/content/renderer/form_autofill_util.h. |
| 1622 * | 1530 * |
| 1623 * @param {HTMLFormElement} formElement A form element to be processed. | 1531 * @param {HTMLFormElement} formElement A form element to be processed. |
| 1624 * @param {number} requirementsMask A mask on the requirement. | |
| 1625 * @return {Array<FormControlElement>} The array of autofillable elements. | 1532 * @return {Array<FormControlElement>} The array of autofillable elements. |
| 1626 */ | 1533 */ |
| 1627 __gCrWeb.autofill.extractAutofillableElementsInForm = function( | 1534 __gCrWeb.autofill.extractAutofillableElementsInForm = function(formElement) { |
| 1628 formElement, requirementsMask) { | |
| 1629 var controlElements = __gCrWeb.common.getFormControlElements(formElement); | 1535 var controlElements = __gCrWeb.common.getFormControlElements(formElement); |
| 1630 return __gCrWeb.autofill.extractAutofillableElementsFromSet( | 1536 return __gCrWeb.autofill.extractAutofillableElementsFromSet(controlElements); |
| 1631 controlElements, requirementsMask); | |
| 1632 }; | 1537 }; |
| 1633 | 1538 |
| 1634 /** | 1539 /** |
| 1635 * Fills out a FormField object from a given form control element. | 1540 * Fills out a FormField object from a given form control element. |
| 1636 * | 1541 * |
| 1637 * It is based on the logic in | 1542 * It is based on the logic in |
| 1638 * void WebFormControlElementToFormField( | 1543 * void WebFormControlElementToFormField( |
| 1639 * const blink::WebFormControlElement& element, | 1544 * const blink::WebFormControlElement& element, |
| 1640 * ExtractMask extract_mask, | 1545 * ExtractMask extract_mask, |
| 1641 * FormFieldData* field); | 1546 * FormFieldData* field); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1746 continue; | 1651 continue; |
| 1747 } | 1652 } |
| 1748 var elementName = __gCrWeb['common'].nameForAutofill(element); | 1653 var elementName = __gCrWeb['common'].nameForAutofill(element); |
| 1749 var value = formData[elementName]; | 1654 var value = formData[elementName]; |
| 1750 if (value) { | 1655 if (value) { |
| 1751 element.placeholder = value; | 1656 element.placeholder = value; |
| 1752 } | 1657 } |
| 1753 } | 1658 } |
| 1754 } | 1659 } |
| 1755 }; | 1660 }; |
| OLD | NEW |