OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "chrome/renderer/autofill/form_autofill_util.h" | 5 #include "chrome/renderer/autofill/form_autofill_util.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_vector.h" | 10 #include "base/memory/scoped_vector.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 using autofill::ExtractAutofillableElements; | 48 using autofill::ExtractAutofillableElements; |
49 using autofill::IsAutofillableInputElement; | 49 using autofill::IsAutofillableInputElement; |
50 using autofill::IsCheckableElement; | 50 using autofill::IsCheckableElement; |
51 using autofill::IsSelectElement; | 51 using autofill::IsSelectElement; |
52 using autofill::IsTextInput; | 52 using autofill::IsTextInput; |
53 | 53 |
54 // The maximum length allowed for form data. | 54 // The maximum length allowed for form data. |
55 const size_t kMaxDataLength = 1024; | 55 const size_t kMaxDataLength = 1024; |
56 | 56 |
57 bool IsOptionElement(const WebElement& element) { | 57 bool IsOptionElement(const WebElement& element) { |
58 return element.hasTagName("option"); | 58 CR_DEFINE_STATIC_LOCAL(WebString, kOption, ("option")); |
| 59 return element.hasTagName(kOption); |
59 } | 60 } |
60 | 61 |
61 bool IsScriptElement(const WebElement& element) { | 62 bool IsScriptElement(const WebElement& element) { |
62 return element.hasTagName("script"); | 63 CR_DEFINE_STATIC_LOCAL(WebString, kScript, ("script")); |
| 64 return element.hasTagName(kScript); |
63 } | 65 } |
64 | 66 |
65 bool IsNoScriptElement(const WebElement& element) { | 67 bool IsNoScriptElement(const WebElement& element) { |
66 return element.hasTagName("noscript"); | 68 CR_DEFINE_STATIC_LOCAL(WebString, kNoScript, ("noscript")); |
| 69 return element.hasTagName(kNoScript); |
67 } | 70 } |
68 | 71 |
69 bool HasTagName(const WebNode& node, const WebKit::WebString& tag) { | 72 bool HasTagName(const WebNode& node, const WebKit::WebString& tag) { |
70 return node.isElementNode() && node.toConst<WebElement>().hasTagName(tag); | 73 return node.isElementNode() && node.toConst<WebElement>().hasTagName(tag); |
71 } | 74 } |
72 | 75 |
73 bool IsAutofillableElement(const WebFormControlElement& element) { | 76 bool IsAutofillableElement(const WebFormControlElement& element) { |
74 const WebInputElement* input_element = toWebInputElement(&element); | 77 const WebInputElement* input_element = toWebInputElement(&element); |
75 return IsAutofillableInputElement(input_element) || IsSelectElement(element); | 78 return IsAutofillableInputElement(input_element) || IsSelectElement(element); |
76 } | 79 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 197 |
195 // Otherwise, only consider normal HTML elements and their contents. | 198 // Otherwise, only consider normal HTML elements and their contents. |
196 if (node_type != WebNode::TextNode && | 199 if (node_type != WebNode::TextNode && |
197 node_type != WebNode::ElementNode) | 200 node_type != WebNode::ElementNode) |
198 break; | 201 break; |
199 | 202 |
200 // A label might be split across multiple "lightweight" nodes. | 203 // A label might be split across multiple "lightweight" nodes. |
201 // Coalesce any text contained in multiple consecutive | 204 // Coalesce any text contained in multiple consecutive |
202 // (a) plain text nodes or | 205 // (a) plain text nodes or |
203 // (b) inline HTML elements that are essentially equivalent to text nodes. | 206 // (b) inline HTML elements that are essentially equivalent to text nodes. |
| 207 CR_DEFINE_STATIC_LOCAL(WebString, kBold, ("b")); |
| 208 CR_DEFINE_STATIC_LOCAL(WebString, kStrong, ("strong")); |
| 209 CR_DEFINE_STATIC_LOCAL(WebString, kSpan, ("span")); |
| 210 CR_DEFINE_STATIC_LOCAL(WebString, kFont, ("font")); |
204 if (previous.isTextNode() || | 211 if (previous.isTextNode() || |
205 HasTagName(previous, "b") || HasTagName(previous, "strong") || | 212 HasTagName(previous, kBold) || HasTagName(previous, kStrong) || |
206 HasTagName(previous, "span") || HasTagName(previous, "font")) { | 213 HasTagName(previous, kSpan) || HasTagName(previous, kFont)) { |
207 string16 value = FindChildText(previous); | 214 string16 value = FindChildText(previous); |
208 // A text node's value will be empty if it is for a line break. | 215 // A text node's value will be empty if it is for a line break. |
209 bool add_space = previous.isTextNode() && value.empty(); | 216 bool add_space = previous.isTextNode() && value.empty(); |
210 inferred_label = | 217 inferred_label = |
211 CombineAndCollapseWhitespace(value, inferred_label, add_space); | 218 CombineAndCollapseWhitespace(value, inferred_label, add_space); |
212 continue; | 219 continue; |
213 } | 220 } |
214 | 221 |
215 // If we have identified a partial label and have reached a non-lightweight | 222 // If we have identified a partial label and have reached a non-lightweight |
216 // element, consider the label to be complete. | 223 // element, consider the label to be complete. |
217 string16 trimmed_label; | 224 string16 trimmed_label; |
218 TrimWhitespace(inferred_label, TRIM_ALL, &trimmed_label); | 225 TrimWhitespace(inferred_label, TRIM_ALL, &trimmed_label); |
219 if (!trimmed_label.empty()) | 226 if (!trimmed_label.empty()) |
220 break; | 227 break; |
221 | 228 |
222 // <img> and <br> tags often appear between the input element and its | 229 // <img> and <br> tags often appear between the input element and its |
223 // label text, so skip over them. | 230 // label text, so skip over them. |
224 if (HasTagName(previous, "img") || HasTagName(previous, "br")) | 231 CR_DEFINE_STATIC_LOCAL(WebString, kImage, ("img")); |
| 232 CR_DEFINE_STATIC_LOCAL(WebString, kBreak, ("br")); |
| 233 if (HasTagName(previous, kImage) || HasTagName(previous, kBreak)) |
225 continue; | 234 continue; |
226 | 235 |
227 // We only expect <p> and <label> tags to contain the full label text. | 236 // We only expect <p> and <label> tags to contain the full label text. |
228 if (HasTagName(previous, "p") || HasTagName(previous, "label")) | 237 CR_DEFINE_STATIC_LOCAL(WebString, kPage, ("p")); |
| 238 CR_DEFINE_STATIC_LOCAL(WebString, kLabel, ("label")); |
| 239 if (HasTagName(previous, kPage) || HasTagName(previous, kLabel)) |
229 inferred_label = FindChildText(previous); | 240 inferred_label = FindChildText(previous); |
230 | 241 |
231 break; | 242 break; |
232 } | 243 } |
233 | 244 |
234 TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label); | 245 TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label); |
235 return inferred_label; | 246 return inferred_label; |
236 } | 247 } |
237 | 248 |
238 // Helper for |InferLabelForElement()| that infers a label, if possible, from | 249 // Helper for |InferLabelForElement()| that infers a label, if possible, from |
239 // enclosing list item, | 250 // enclosing list item, |
240 // e.g. <li>Some Text<input ...><input ...><input ...></tr> | 251 // e.g. <li>Some Text<input ...><input ...><input ...></tr> |
241 string16 InferLabelFromListItem(const WebFormControlElement& element) { | 252 string16 InferLabelFromListItem(const WebFormControlElement& element) { |
242 WebNode parent = element.parentNode(); | 253 WebNode parent = element.parentNode(); |
| 254 CR_DEFINE_STATIC_LOCAL(WebString, kListItem, ("li")); |
243 while (!parent.isNull() && parent.isElementNode() && | 255 while (!parent.isNull() && parent.isElementNode() && |
244 !parent.to<WebElement>().hasTagName("li")) { | 256 !parent.to<WebElement>().hasTagName(kListItem)) { |
245 parent = parent.parentNode(); | 257 parent = parent.parentNode(); |
246 } | 258 } |
247 | 259 |
248 if (!parent.isNull() && HasTagName(parent, "li")) | 260 if (!parent.isNull() && HasTagName(parent, kListItem)) |
249 return FindChildText(parent); | 261 return FindChildText(parent); |
250 | 262 |
251 return string16(); | 263 return string16(); |
252 } | 264 } |
253 | 265 |
254 // Helper for |InferLabelForElement()| that infers a label, if possible, from | 266 // Helper for |InferLabelForElement()| that infers a label, if possible, from |
255 // surrounding table structure, | 267 // surrounding table structure, |
256 // e.g. <tr><td>Some Text</td><td><input ...></td></tr> | 268 // e.g. <tr><td>Some Text</td><td><input ...></td></tr> |
257 // or <tr><th>Some Text</th><td><input ...></td></tr> | 269 // or <tr><th>Some Text</th><td><input ...></td></tr> |
258 // or <tr><td><b>Some Text</b></td><td><b><input ...></b></td></tr> | 270 // or <tr><td><b>Some Text</b></td><td><b><input ...></b></td></tr> |
259 // or <tr><th><b>Some Text</b></th><td><b><input ...></b></td></tr> | 271 // or <tr><th><b>Some Text</b></th><td><b><input ...></b></td></tr> |
260 string16 InferLabelFromTableColumn(const WebFormControlElement& element) { | 272 string16 InferLabelFromTableColumn(const WebFormControlElement& element) { |
| 273 CR_DEFINE_STATIC_LOCAL(WebString, kTableCell, ("td")); |
261 WebNode parent = element.parentNode(); | 274 WebNode parent = element.parentNode(); |
262 while (!parent.isNull() && parent.isElementNode() && | 275 while (!parent.isNull() && parent.isElementNode() && |
263 !parent.to<WebElement>().hasTagName("td")) { | 276 !parent.to<WebElement>().hasTagName(kTableCell)) { |
264 parent = parent.parentNode(); | 277 parent = parent.parentNode(); |
265 } | 278 } |
266 | 279 |
267 if (parent.isNull()) | 280 if (parent.isNull()) |
268 return string16(); | 281 return string16(); |
269 | 282 |
270 // Check all previous siblings, skipping non-element nodes, until we find a | 283 // Check all previous siblings, skipping non-element nodes, until we find a |
271 // non-empty text block. | 284 // non-empty text block. |
272 string16 inferred_label; | 285 string16 inferred_label; |
273 WebNode previous = parent.previousSibling(); | 286 WebNode previous = parent.previousSibling(); |
| 287 CR_DEFINE_STATIC_LOCAL(WebString, kTableHeader, ("th")); |
274 while (inferred_label.empty() && !previous.isNull()) { | 288 while (inferred_label.empty() && !previous.isNull()) { |
275 if (HasTagName(previous, "td") || HasTagName(previous, "th")) | 289 if (HasTagName(previous, kTableCell) || HasTagName(previous, kTableHeader)) |
276 inferred_label = FindChildText(previous); | 290 inferred_label = FindChildText(previous); |
277 | 291 |
278 previous = previous.previousSibling(); | 292 previous = previous.previousSibling(); |
279 } | 293 } |
280 | 294 |
281 return inferred_label; | 295 return inferred_label; |
282 } | 296 } |
283 | 297 |
284 // Helper for |InferLabelForElement()| that infers a label, if possible, from | 298 // Helper for |InferLabelForElement()| that infers a label, if possible, from |
285 // surrounding table structure, | 299 // surrounding table structure, |
286 // e.g. <tr><td>Some Text</td></tr><tr><td><input ...></td></tr> | 300 // e.g. <tr><td>Some Text</td></tr><tr><td><input ...></td></tr> |
287 string16 InferLabelFromTableRow(const WebFormControlElement& element) { | 301 string16 InferLabelFromTableRow(const WebFormControlElement& element) { |
| 302 CR_DEFINE_STATIC_LOCAL(WebString, kTableRow, ("tr")); |
288 WebNode parent = element.parentNode(); | 303 WebNode parent = element.parentNode(); |
289 while (!parent.isNull() && parent.isElementNode() && | 304 while (!parent.isNull() && parent.isElementNode() && |
290 !parent.to<WebElement>().hasTagName("tr")) { | 305 !parent.to<WebElement>().hasTagName(kTableRow)) { |
291 parent = parent.parentNode(); | 306 parent = parent.parentNode(); |
292 } | 307 } |
293 | 308 |
294 if (parent.isNull()) | 309 if (parent.isNull()) |
295 return string16(); | 310 return string16(); |
296 | 311 |
297 // Check all previous siblings, skipping non-element nodes, until we find a | 312 // Check all previous siblings, skipping non-element nodes, until we find a |
298 // non-empty text block. | 313 // non-empty text block. |
299 string16 inferred_label; | 314 string16 inferred_label; |
300 WebNode previous = parent.previousSibling(); | 315 WebNode previous = parent.previousSibling(); |
301 while (inferred_label.empty() && !previous.isNull()) { | 316 while (inferred_label.empty() && !previous.isNull()) { |
302 if (HasTagName(previous, "tr")) | 317 if (HasTagName(previous, kTableRow)) |
303 inferred_label = FindChildText(previous); | 318 inferred_label = FindChildText(previous); |
304 | 319 |
305 previous = previous.previousSibling(); | 320 previous = previous.previousSibling(); |
306 } | 321 } |
307 | 322 |
308 return inferred_label; | 323 return inferred_label; |
309 } | 324 } |
310 | 325 |
311 // Helper for |InferLabelForElement()| that infers a label, if possible, from | 326 // Helper for |InferLabelForElement()| that infers a label, if possible, from |
312 // a surrounding div table, | 327 // a surrounding div table, |
313 // e.g. <div>Some Text<span><input ...></span></div> | 328 // e.g. <div>Some Text<span><input ...></span></div> |
314 // e.g. <div>Some Text</div><div><input ...></div> | 329 // e.g. <div>Some Text</div><div><input ...></div> |
315 string16 InferLabelFromDivTable(const WebFormControlElement& element) { | 330 string16 InferLabelFromDivTable(const WebFormControlElement& element) { |
316 WebNode node = element.parentNode(); | 331 WebNode node = element.parentNode(); |
317 bool looking_for_parent = true; | 332 bool looking_for_parent = true; |
318 | 333 |
319 // Search the sibling and parent <div>s until we find a candidate label. | 334 // Search the sibling and parent <div>s until we find a candidate label. |
320 string16 inferred_label; | 335 string16 inferred_label; |
| 336 CR_DEFINE_STATIC_LOCAL(WebString, kDiv, ("div")); |
| 337 CR_DEFINE_STATIC_LOCAL(WebString, kTable, ("table")); |
| 338 CR_DEFINE_STATIC_LOCAL(WebString, kFieldSet, ("fieldset")); |
321 while (inferred_label.empty() && !node.isNull()) { | 339 while (inferred_label.empty() && !node.isNull()) { |
322 if (HasTagName(node, "div")) { | 340 if (HasTagName(node, kDiv)) { |
323 looking_for_parent = false; | 341 looking_for_parent = false; |
324 inferred_label = FindChildText(node); | 342 inferred_label = FindChildText(node); |
325 } else if (looking_for_parent && | 343 } else if (looking_for_parent && |
326 (HasTagName(node, "table") || HasTagName(node, "fieldset"))) { | 344 (HasTagName(node, kTable) || HasTagName(node, kFieldSet))) { |
327 // If the element is in a table or fieldset, its label most likely is too. | 345 // If the element is in a table or fieldset, its label most likely is too. |
328 break; | 346 break; |
329 } | 347 } |
330 | 348 |
331 if (node.previousSibling().isNull()) { | 349 if (node.previousSibling().isNull()) { |
332 // If there are no more siblings, continue walking up the tree. | 350 // If there are no more siblings, continue walking up the tree. |
333 looking_for_parent = true; | 351 looking_for_parent = true; |
334 } | 352 } |
335 | 353 |
336 if (looking_for_parent) | 354 if (looking_for_parent) |
337 node = node.parentNode(); | 355 node = node.parentNode(); |
338 else | 356 else |
339 node = node.previousSibling(); | 357 node = node.previousSibling(); |
340 } | 358 } |
341 | 359 |
342 return inferred_label; | 360 return inferred_label; |
343 } | 361 } |
344 | 362 |
345 // Helper for |InferLabelForElement()| that infers a label, if possible, from | 363 // Helper for |InferLabelForElement()| that infers a label, if possible, from |
346 // a surrounding definition list, | 364 // a surrounding definition list, |
347 // e.g. <dl><dt>Some Text</dt><dd><input ...></dd></dl> | 365 // e.g. <dl><dt>Some Text</dt><dd><input ...></dd></dl> |
348 // e.g. <dl><dt><b>Some Text</b></dt><dd><b><input ...></b></dd></dl> | 366 // e.g. <dl><dt><b>Some Text</b></dt><dd><b><input ...></b></dd></dl> |
349 string16 InferLabelFromDefinitionList(const WebFormControlElement& element) { | 367 string16 InferLabelFromDefinitionList(const WebFormControlElement& element) { |
| 368 CR_DEFINE_STATIC_LOCAL(WebString, kDefinitionData, ("dd")); |
350 WebNode parent = element.parentNode(); | 369 WebNode parent = element.parentNode(); |
351 while (!parent.isNull() && parent.isElementNode() && | 370 while (!parent.isNull() && parent.isElementNode() && |
352 !parent.to<WebElement>().hasTagName("dd")) | 371 !parent.to<WebElement>().hasTagName(kDefinitionData)) |
353 parent = parent.parentNode(); | 372 parent = parent.parentNode(); |
354 | 373 |
355 if (parent.isNull() || !HasTagName(parent, "dd")) | 374 if (parent.isNull() || !HasTagName(parent, kDefinitionData)) |
356 return string16(); | 375 return string16(); |
357 | 376 |
358 // Skip by any intervening text nodes. | 377 // Skip by any intervening text nodes. |
359 WebNode previous = parent.previousSibling(); | 378 WebNode previous = parent.previousSibling(); |
360 while (!previous.isNull() && previous.isTextNode()) | 379 while (!previous.isNull() && previous.isTextNode()) |
361 previous = previous.previousSibling(); | 380 previous = previous.previousSibling(); |
362 | 381 |
363 if (previous.isNull() || !HasTagName(previous, "dt")) | 382 CR_DEFINE_STATIC_LOCAL(WebString, kDefinitionTag, ("dt")); |
| 383 if (previous.isNull() || !HasTagName(previous, kDefinitionTag)) |
364 return string16(); | 384 return string16(); |
365 | 385 |
366 return FindChildText(previous); | 386 return FindChildText(previous); |
367 } | 387 } |
368 | 388 |
369 // Infers corresponding label for |element| from surrounding context in the DOM, | 389 // Infers corresponding label for |element| from surrounding context in the DOM, |
370 // e.g. the contents of the preceding <p> tag or text element. | 390 // e.g. the contents of the preceding <p> tag or text element. |
371 string16 InferLabelForElement(const WebFormControlElement& element) { | 391 string16 InferLabelForElement(const WebFormControlElement& element) { |
372 string16 inferred_label = InferLabelFromPrevious(element); | 392 string16 inferred_label = InferLabelFromPrevious(element); |
373 if (!inferred_label.empty()) | 393 if (!inferred_label.empty()) |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 } | 606 } |
587 | 607 |
588 bool IsAutofillableInputElement(const WebInputElement* element) { | 608 bool IsAutofillableInputElement(const WebInputElement* element) { |
589 // TODO(ramankk): Uncomment IsCheckableElement part once we have solution | 609 // TODO(ramankk): Uncomment IsCheckableElement part once we have solution |
590 // for the observed performance regression. | 610 // for the observed performance regression. |
591 return IsTextInput(element); // || IsCheckableElement(element); | 611 return IsTextInput(element); // || IsCheckableElement(element); |
592 } | 612 } |
593 | 613 |
594 const string16 GetFormIdentifier(const WebFormElement& form) { | 614 const string16 GetFormIdentifier(const WebFormElement& form) { |
595 string16 identifier = form.name(); | 615 string16 identifier = form.name(); |
| 616 CR_DEFINE_STATIC_LOCAL(WebString, kId, ("id")); |
596 if (identifier.empty()) | 617 if (identifier.empty()) |
597 identifier = form.getAttribute(WebString("id")); | 618 identifier = form.getAttribute(kId); |
598 | 619 |
599 return identifier; | 620 return identifier; |
600 } | 621 } |
601 | 622 |
602 bool ClickElement(const WebDocument& document, | 623 bool ClickElement(const WebDocument& document, |
603 const WebElementDescriptor& element_descriptor) { | 624 const WebElementDescriptor& element_descriptor) { |
604 WebString web_descriptor = WebString::fromUTF8(element_descriptor.descriptor); | 625 WebString web_descriptor = WebString::fromUTF8(element_descriptor.descriptor); |
605 WebKit::WebElement element; | 626 WebKit::WebElement element; |
606 | 627 |
607 switch (element_descriptor.retrieval_method) { | 628 switch (element_descriptor.retrieval_method) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 | 677 |
657 autofillable_elements->push_back(element); | 678 autofillable_elements->push_back(element); |
658 } | 679 } |
659 } | 680 } |
660 | 681 |
661 void WebFormControlElementToFormField(const WebFormControlElement& element, | 682 void WebFormControlElementToFormField(const WebFormControlElement& element, |
662 ExtractMask extract_mask, | 683 ExtractMask extract_mask, |
663 FormFieldData* field) { | 684 FormFieldData* field) { |
664 DCHECK(field); | 685 DCHECK(field); |
665 DCHECK(!element.isNull()); | 686 DCHECK(!element.isNull()); |
| 687 CR_DEFINE_STATIC_LOCAL(WebString, kAutocomplete, ("autocomplete")); |
666 | 688 |
667 // The label is not officially part of a WebFormControlElement; however, the | 689 // The label is not officially part of a WebFormControlElement; however, the |
668 // labels for all form control elements are scraped from the DOM and set in | 690 // labels for all form control elements are scraped from the DOM and set in |
669 // WebFormElementToFormData. | 691 // WebFormElementToFormData. |
670 field->name = element.nameForAutofill(); | 692 field->name = element.nameForAutofill(); |
671 field->form_control_type = UTF16ToUTF8(element.formControlType()); | 693 field->form_control_type = UTF16ToUTF8(element.formControlType()); |
672 field->autocomplete_attribute = | 694 field->autocomplete_attribute = |
673 UTF16ToUTF8(element.getAttribute("autocomplete")); | 695 UTF16ToUTF8(element.getAttribute(kAutocomplete)); |
674 if (field->autocomplete_attribute.size() > kMaxDataLength) { | 696 if (field->autocomplete_attribute.size() > kMaxDataLength) { |
675 // Discard overly long attribute values to avoid DOS-ing the browser | 697 // Discard overly long attribute values to avoid DOS-ing the browser |
676 // process. However, send over a default string to indicate that the | 698 // process. However, send over a default string to indicate that the |
677 // attribute was present. | 699 // attribute was present. |
678 field->autocomplete_attribute = "x-max-data-length-exceeded"; | 700 field->autocomplete_attribute = "x-max-data-length-exceeded"; |
679 } | 701 } |
680 | 702 |
681 if (!IsAutofillableElement(element)) | 703 if (!IsAutofillableElement(element)) |
682 return; | 704 return; |
683 | 705 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 field->value = value; | 756 field->value = value; |
735 } | 757 } |
736 | 758 |
737 bool WebFormElementToFormData( | 759 bool WebFormElementToFormData( |
738 const WebKit::WebFormElement& form_element, | 760 const WebKit::WebFormElement& form_element, |
739 const WebKit::WebFormControlElement& form_control_element, | 761 const WebKit::WebFormControlElement& form_control_element, |
740 RequirementsMask requirements, | 762 RequirementsMask requirements, |
741 ExtractMask extract_mask, | 763 ExtractMask extract_mask, |
742 FormData* form, | 764 FormData* form, |
743 FormFieldData* field) { | 765 FormFieldData* field) { |
| 766 CR_DEFINE_STATIC_LOCAL(WebString, kLabel, ("label")); |
| 767 CR_DEFINE_STATIC_LOCAL(WebString, kFor, ("for")); |
| 768 CR_DEFINE_STATIC_LOCAL(WebString, kHidden, ("hidden")); |
| 769 |
744 const WebFrame* frame = form_element.document().frame(); | 770 const WebFrame* frame = form_element.document().frame(); |
745 if (!frame) | 771 if (!frame) |
746 return false; | 772 return false; |
747 | 773 |
748 if (requirements & REQUIRE_AUTOCOMPLETE && !form_element.autoComplete()) | 774 if (requirements & REQUIRE_AUTOCOMPLETE && !form_element.autoComplete()) |
749 return false; | 775 return false; |
750 | 776 |
751 form->name = GetFormIdentifier(form_element); | 777 form->name = GetFormIdentifier(form_element); |
752 form->method = form_element.method(); | 778 form->method = form_element.method(); |
753 form->origin = frame->document().url(); | 779 form->origin = frame->document().url(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 // If we failed to extract any fields, give up. Also, to avoid overly | 825 // If we failed to extract any fields, give up. Also, to avoid overly |
800 // expensive computation, we impose a maximum number of allowable fields. | 826 // expensive computation, we impose a maximum number of allowable fields. |
801 if (form_fields.empty() || form_fields.size() > kMaxParseableFields) | 827 if (form_fields.empty() || form_fields.size() > kMaxParseableFields) |
802 return false; | 828 return false; |
803 | 829 |
804 // Loop through the label elements inside the form element. For each label | 830 // Loop through the label elements inside the form element. For each label |
805 // element, get the corresponding form control element, use the form control | 831 // element, get the corresponding form control element, use the form control |
806 // element's name as a key into the <name, FormFieldData> map to find the | 832 // element's name as a key into the <name, FormFieldData> map to find the |
807 // previously created FormFieldData and set the FormFieldData's label to the | 833 // previously created FormFieldData and set the FormFieldData's label to the |
808 // label.firstChild().nodeValue() of the label element. | 834 // label.firstChild().nodeValue() of the label element. |
809 WebNodeList labels = form_element.getElementsByTagName("label"); | 835 WebNodeList labels = form_element.getElementsByTagName(kLabel); |
810 for (unsigned i = 0; i < labels.length(); ++i) { | 836 for (unsigned i = 0; i < labels.length(); ++i) { |
811 WebLabelElement label = labels.item(i).to<WebLabelElement>(); | 837 WebLabelElement label = labels.item(i).to<WebLabelElement>(); |
812 WebFormControlElement field_element = | 838 WebFormControlElement field_element = |
813 label.correspondingControl().to<WebFormControlElement>(); | 839 label.correspondingControl().to<WebFormControlElement>(); |
814 | 840 |
815 string16 element_name; | 841 string16 element_name; |
816 if (field_element.isNull()) { | 842 if (field_element.isNull()) { |
817 // Sometimes site authors will incorrectly specify the corresponding | 843 // Sometimes site authors will incorrectly specify the corresponding |
818 // field element's name rather than its id, so we compensate here. | 844 // field element's name rather than its id, so we compensate here. |
819 element_name = label.getAttribute("for"); | 845 element_name = label.getAttribute(kFor); |
820 } else if ( | 846 } else if ( |
821 !field_element.isFormControlElement() || | 847 !field_element.isFormControlElement() || |
822 field_element.formControlType() == WebString::fromUTF8("hidden")) { | 848 field_element.formControlType() == kHidden) { |
823 continue; | 849 continue; |
824 } else { | 850 } else { |
825 element_name = field_element.nameForAutofill(); | 851 element_name = field_element.nameForAutofill(); |
826 } | 852 } |
827 | 853 |
828 std::map<string16, FormFieldData*>::iterator iter = | 854 std::map<string16, FormFieldData*>::iterator iter = |
829 name_map.find(element_name); | 855 name_map.find(element_name); |
830 if (iter != name_map.end()) { | 856 if (iter != name_map.end()) { |
831 string16 label_text = FindChildText(label); | 857 string16 label_text = FindChildText(label); |
832 | 858 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 continue; | 1013 continue; |
988 | 1014 |
989 if (input_element->isAutofilled()) | 1015 if (input_element->isAutofilled()) |
990 return true; | 1016 return true; |
991 } | 1017 } |
992 | 1018 |
993 return false; | 1019 return false; |
994 } | 1020 } |
995 | 1021 |
996 } // namespace autofill | 1022 } // namespace autofill |
OLD | NEW |