Index: chrome/renderer/autofill/autofill_agent.cc |
diff --git a/chrome/renderer/autofill/autofill_agent.cc b/chrome/renderer/autofill/autofill_agent.cc |
index 73baa1f81f024d11d04684b8c84081f43594cf48..ab6383b3bef86488c11c6f7ac1e5db12955ff74b 100644 |
--- a/chrome/renderer/autofill/autofill_agent.cc |
+++ b/chrome/renderer/autofill/autofill_agent.cc |
@@ -7,6 +7,8 @@ |
#include "base/bind.h" |
#include "base/message_loop.h" |
#include "base/time.h" |
+#include "base/string_util.h" |
+#include "base/string_split.h" |
#include "base/utf_string_conversions.h" |
#include "chrome/common/autofill_messages.h" |
#include "chrome/common/chrome_constants.h" |
@@ -43,7 +45,7 @@ using WebKit::WebOptionElement; |
using WebKit::WebString; |
using webkit::forms::FormData; |
using webkit::forms::FormDataPredictions; |
- |
+#include <iostream> |
Ilya Sherman
2012/05/07 23:34:52
nit: Did you mean to add this #include, or was it
keishi
2012/05/09 01:38:21
Sorry my mistake.
|
namespace { |
// The size above which we stop triggering autofill for an input text field |
@@ -59,9 +61,17 @@ void AppendDataListSuggestions(const WebKit::WebInputElement& element, |
if (options.isNull()) |
return; |
+ string16 prefix = element.editingValue(); |
Ilya Sherman
2012/05/07 23:34:52
What is the difference between element.value() and
keishi
2012/05/09 01:38:21
There is no difference for <input type=text>. But
|
+ if (element.isMultiple() && |
+ element.formControlType() == WebString::fromUTF8("email")) { |
+ std::vector<string16> parts; |
+ base::SplitStringDontTrim(prefix, ',', &parts); |
+ if (parts.size() > 0) |
+ TrimWhitespace(parts[parts.size() - 1], TRIM_LEADING, &prefix); |
+ } |
for (WebOptionElement option = options.firstItem().to<WebOptionElement>(); |
!option.isNull(); option = options.nextItem().to<WebOptionElement>()) { |
Ilya Sherman
2012/05/07 23:34:52
nit: This line should be indented one more space.
keishi
2012/05/09 01:38:21
ok.
|
- if (!StartsWith(option.value(), element.value(), false)) |
+ if (!StartsWith(option.value(), prefix, false)) |
continue; |
values->push_back(option.value()); |
@@ -209,11 +219,37 @@ void AutofillAgent::didAcceptAutofillSuggestion(const WebNode& node, |
break; |
case WebAutofillClient::MenuItemIDAutocompleteEntry: |
case WebAutofillClient::MenuItemIDPasswordEntry: |
- case WebAutofillClient::MenuItemIDDataListEntry: |
- // User selected an Autocomplete or password or datalist entry, so we |
- // fill directly. |
+ // User selected an Autocomplete or password entry, so we fill directly. |
SetNodeText(value, &element_); |
break; |
+ case WebAutofillClient::MenuItemIDDataListEntry: { |
+ string16 new_value = value; |
+ // If this element takes multiple values then replace the last part with |
+ // the suggestion. |
+ if (element_.isMultiple() && |
+ element_.formControlType() == WebString::fromUTF8("email")) { |
+ std::vector<string16> parts; |
+ |
+ base::SplitStringDontTrim(element_.editingValue(), ',', &parts); |
+ if (parts.size() == 0) |
+ parts.push_back(string16()); |
+ |
+ string16 last_part = parts.back(); |
+ // We want to keep just the leading whitespace. |
+ for (size_t i = 0; i < last_part.size(); ++i) { |
+ if (!IsWhitespace(last_part[i])) { |
+ last_part = last_part.substr(0, i); |
+ break; |
+ } |
+ } |
+ last_part.append(value); |
+ parts[parts.size() - 1] = last_part; |
+ |
+ new_value = JoinString(parts, ','); |
+ } |
+ SetNodeText(new_value, &element_); |
+ break; |
+ } |
default: |
// A positive item_id is a unique id for an autofill (vs. autocomplete) |
// suggestion. |
@@ -413,7 +449,7 @@ void AutofillAgent::CombineDataListEntriesAndShow( |
if (v.empty()) { |
// No suggestions, any popup currently showing is obsolete. |
- web_view->hidePopups(); |
+ HidePopups(); |
return; |
} |
@@ -502,16 +538,14 @@ void AutofillAgent::ShowSuggestions(const WebInputElement& element, |
// Don't attempt to autofill with values that are too large or if filling |
// criteria are not met. |
- WebString value = element.value(); |
+ WebString value = element.editingValue(); |
if (value.length() > kMaximumTextSizeForAutofill || |
(!autofill_on_empty_values && value.isEmpty()) || |
(requires_caret_at_end && |
(element.selectionStart() != element.selectionEnd() || |
element.selectionEnd() != static_cast<int>(value.length())))) { |
// Any popup currently showing is obsolete. |
- WebKit::WebView* web_view = render_view()->GetWebView(); |
- if (web_view) |
- web_view->hidePopups(); |
+ HidePopups(); |
return; |
} |
@@ -586,7 +620,23 @@ void AutofillAgent::SetNodeText(const string16& value, |
string16 substring = value; |
substring = substring.substr(0, node->maxLength()); |
- node->setValue(substring, true); |
+ WebKit::WebView* web_view = render_view()->GetWebView(); |
+ if (!web_view || !web_view->focusedFrame()) |
+ return; |
+ |
+ web_view->focusedFrame()->executeCommand(WebString::fromUTF8("selectAll")); |
+ web_view->focusedFrame()->executeCommand(WebString::fromUTF8("InsertText"), |
+ substring); |
Ilya Sherman
2012/05/07 23:34:52
Is there really no more direct way to achieve the
keishi
2012/05/09 01:38:21
There is an inner text field that's being edited b
Ilya Sherman
2012/05/09 02:38:58
If we are exposing |editingValue()|, it makes sens
|
+ weak_ptr_factory_.InvalidateWeakPtrs(); |
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(&AutofillAgent::HidePopups, |
+ weak_ptr_factory_.GetWeakPtr())); |
Ilya Sherman
2012/05/07 23:34:52
Hmm, I don't understand the motivation for the cha
keishi
2012/05/09 01:38:21
if you do setValue("a@.com, b@b.com"), the text fi
|
+} |
+ |
+void AutofillAgent::HidePopups() { |
+ WebKit::WebView* web_view = render_view()->GetWebView(); |
+ if (web_view) |
+ web_view->hidePopups(); |
} |
} // namespace autofill |