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 #include "components/autofill/content/renderer/form_autofill_util.h" | 5 #include "components/autofill/content/renderer/form_autofill_util.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 previous = previous.previousSibling(); | 528 previous = previous.previousSibling(); |
529 } | 529 } |
530 | 530 |
531 return inferred_label; | 531 return inferred_label; |
532 } | 532 } |
533 | 533 |
534 // Helper for |InferLabelForElement()| that infers a label, if possible, from | 534 // Helper for |InferLabelForElement()| that infers a label, if possible, from |
535 // a surrounding div table, | 535 // a surrounding div table, |
536 // e.g. <div>Some Text<span><input ...></span></div> | 536 // e.g. <div>Some Text<span><input ...></span></div> |
537 // e.g. <div>Some Text</div><div><input ...></div> | 537 // e.g. <div>Some Text</div><div><input ...></div> |
| 538 // |
| 539 // Because this is already traversing the <div> structure, if it finds a <label> |
| 540 // sibling along the way, infer from that <label>. |
538 base::string16 InferLabelFromDivTable(const WebFormControlElement& element) { | 541 base::string16 InferLabelFromDivTable(const WebFormControlElement& element) { |
539 WebNode node = element.parentNode(); | 542 WebNode node = element.parentNode(); |
540 bool looking_for_parent = true; | 543 bool looking_for_parent = true; |
541 std::set<WebNode> divs_to_skip; | 544 std::set<WebNode> divs_to_skip; |
542 | 545 |
543 // Search the sibling and parent <div>s until we find a candidate label. | 546 // Search the sibling and parent <div>s until we find a candidate label. |
544 base::string16 inferred_label; | 547 base::string16 inferred_label; |
545 CR_DEFINE_STATIC_LOCAL(WebString, kDiv, ("div")); | 548 CR_DEFINE_STATIC_LOCAL(WebString, kDiv, ("div")); |
546 CR_DEFINE_STATIC_LOCAL(WebString, kTable, ("table")); | 549 CR_DEFINE_STATIC_LOCAL(WebString, kTable, ("table")); |
547 CR_DEFINE_STATIC_LOCAL(WebString, kFieldSet, ("fieldset")); | 550 CR_DEFINE_STATIC_LOCAL(WebString, kFieldSet, ("fieldset")); |
| 551 CR_DEFINE_STATIC_LOCAL(WebString, kLabel, ("label")); |
548 while (inferred_label.empty() && !node.isNull()) { | 552 while (inferred_label.empty() && !node.isNull()) { |
549 if (HasTagName(node, kDiv)) { | 553 if (HasTagName(node, kDiv)) { |
550 if (looking_for_parent) | 554 if (looking_for_parent) |
551 inferred_label = FindChildTextWithIgnoreList(node, divs_to_skip); | 555 inferred_label = FindChildTextWithIgnoreList(node, divs_to_skip); |
552 else | 556 else |
553 inferred_label = FindChildText(node); | 557 inferred_label = FindChildText(node); |
554 | 558 |
555 // Avoid sibling DIVs that contain autofillable fields. | 559 // Avoid sibling DIVs that contain autofillable fields. |
556 if (!looking_for_parent && !inferred_label.empty()) { | 560 if (!looking_for_parent && !inferred_label.empty()) { |
557 CR_DEFINE_STATIC_LOCAL(WebString, kSelector, | 561 CR_DEFINE_STATIC_LOCAL(WebString, kSelector, |
558 ("input, select, textarea")); | 562 ("input, select, textarea")); |
559 blink::WebExceptionCode ec = 0; | 563 blink::WebExceptionCode ec = 0; |
560 WebElement result_element = node.querySelector(kSelector, ec); | 564 WebElement result_element = node.querySelector(kSelector, ec); |
561 if (!result_element.isNull()) { | 565 if (!result_element.isNull()) { |
562 inferred_label.clear(); | 566 inferred_label.clear(); |
563 divs_to_skip.insert(node); | 567 divs_to_skip.insert(node); |
564 } | 568 } |
565 } | 569 } |
566 | 570 |
567 looking_for_parent = false; | 571 looking_for_parent = false; |
| 572 } else if (!looking_for_parent && HasTagName(node, kLabel)) { |
| 573 WebLabelElement label_element = node.to<WebLabelElement>(); |
| 574 if (label_element.correspondingControl().isNull()) |
| 575 inferred_label = FindChildText(node); |
568 } else if (looking_for_parent && | 576 } else if (looking_for_parent && |
569 (HasTagName(node, kTable) || HasTagName(node, kFieldSet))) { | 577 (HasTagName(node, kTable) || HasTagName(node, kFieldSet))) { |
570 // If the element is in a table or fieldset, its label most likely is too. | 578 // If the element is in a table or fieldset, its label most likely is too. |
571 break; | 579 break; |
572 } | 580 } |
573 | 581 |
574 if (node.previousSibling().isNull()) { | 582 if (node.previousSibling().isNull()) { |
575 // If there are no more siblings, continue walking up the tree. | 583 // If there are no more siblings, continue walking up the tree. |
576 looking_for_parent = true; | 584 looking_for_parent = true; |
577 } | 585 } |
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1530 | 1538 |
1531 gfx::RectF GetScaledBoundingBox(float scale, WebElement* element) { | 1539 gfx::RectF GetScaledBoundingBox(float scale, WebElement* element) { |
1532 gfx::Rect bounding_box(element->boundsInViewportSpace()); | 1540 gfx::Rect bounding_box(element->boundsInViewportSpace()); |
1533 return gfx::RectF(bounding_box.x() * scale, | 1541 return gfx::RectF(bounding_box.x() * scale, |
1534 bounding_box.y() * scale, | 1542 bounding_box.y() * scale, |
1535 bounding_box.width() * scale, | 1543 bounding_box.width() * scale, |
1536 bounding_box.height() * scale); | 1544 bounding_box.height() * scale); |
1537 } | 1545 } |
1538 | 1546 |
1539 } // namespace autofill | 1547 } // namespace autofill |
OLD | NEW |