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 |