Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: chrome/renderer/autofill/autofill_agent.cc

Issue 10307004: Support datalist UI for <input type=email multiple> (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Using newly added WebInputType::setEditingValue Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/autofill_agent.h" 5 #include "chrome/renderer/autofill/autofill_agent.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/time.h" 9 #include "base/time.h"
10 #include "base/string_util.h"
11 #include "base/string_split.h"
Ilya Sherman 2012/05/15 21:12:39 nit: These should precede the time.h include.
keishi 2012/05/16 11:44:07 Done.
10 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
11 #include "chrome/common/autofill_messages.h" 13 #include "chrome/common/autofill_messages.h"
12 #include "chrome/common/chrome_constants.h" 14 #include "chrome/common/chrome_constants.h"
13 #include "chrome/renderer/autofill/form_autofill_util.h" 15 #include "chrome/renderer/autofill/form_autofill_util.h"
14 #include "chrome/renderer/autofill/password_autofill_manager.h" 16 #include "chrome/renderer/autofill/password_autofill_manager.h"
15 #include "content/public/renderer/render_view.h" 17 #include "content/public/renderer/render_view.h"
16 #include "grit/chromium_strings.h" 18 #include "grit/chromium_strings.h"
17 #include "grit/generated_resources.h" 19 #include "grit/generated_resources.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" 20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 54
53 void AppendDataListSuggestions(const WebKit::WebInputElement& element, 55 void AppendDataListSuggestions(const WebKit::WebInputElement& element,
54 std::vector<string16>* values, 56 std::vector<string16>* values,
55 std::vector<string16>* labels, 57 std::vector<string16>* labels,
56 std::vector<string16>* icons, 58 std::vector<string16>* icons,
57 std::vector<int>* item_ids) { 59 std::vector<int>* item_ids) {
58 WebNodeCollection options = element.dataListOptions(); 60 WebNodeCollection options = element.dataListOptions();
59 if (options.isNull()) 61 if (options.isNull())
60 return; 62 return;
61 63
64 string16 prefix = element.editingValue();
65 if (element.isMultiple() &&
66 element.formControlType() == WebString::fromUTF8("email")) {
67 std::vector<string16> parts;
68 base::SplitStringDontTrim(prefix, ',', &parts);
69 if (parts.size() > 0)
70 TrimWhitespace(parts[parts.size() - 1], TRIM_LEADING, &prefix);
71 }
62 for (WebOptionElement option = options.firstItem().to<WebOptionElement>(); 72 for (WebOptionElement option = options.firstItem().to<WebOptionElement>();
63 !option.isNull(); option = options.nextItem().to<WebOptionElement>()) { 73 !option.isNull(); option = options.nextItem().to<WebOptionElement>()) {
64 if (!StartsWith(option.value(), element.value(), false)) 74 if (!StartsWith(option.value(), prefix, false) || option.value() == prefix)
Ilya Sherman 2012/05/15 21:12:39 nit: Do you really need the "option.value() == pre
keishi 2012/05/16 11:44:07 This removes suggestions that completely matches t
Ilya Sherman 2012/05/16 18:05:31 Ah, I see, that makes sense. Thanks.
65 continue; 75 continue;
66 76
67 values->push_back(option.value()); 77 values->push_back(option.value());
68 if (option.value() != option.label()) 78 if (option.value() != option.label())
69 labels->push_back(option.label()); 79 labels->push_back(option.label());
70 else 80 else
71 labels->push_back(string16()); 81 labels->push_back(string16());
72 icons->push_back(string16()); 82 icons->push_back(string16());
73 item_ids->push_back(WebAutofillClient::MenuItemIDDataListEntry); 83 item_ids->push_back(WebAutofillClient::MenuItemIDDataListEntry);
74 } 84 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 case WebAutofillClient::MenuItemIDAutofillOptions: 212 case WebAutofillClient::MenuItemIDAutofillOptions:
203 // User selected 'Autofill Options'. 213 // User selected 'Autofill Options'.
204 Send(new AutofillHostMsg_ShowAutofillDialog(routing_id())); 214 Send(new AutofillHostMsg_ShowAutofillDialog(routing_id()));
205 break; 215 break;
206 case WebAutofillClient::MenuItemIDClearForm: 216 case WebAutofillClient::MenuItemIDClearForm:
207 // User selected 'Clear form'. 217 // User selected 'Clear form'.
208 form_cache_.ClearFormWithElement(element_); 218 form_cache_.ClearFormWithElement(element_);
209 break; 219 break;
210 case WebAutofillClient::MenuItemIDAutocompleteEntry: 220 case WebAutofillClient::MenuItemIDAutocompleteEntry:
211 case WebAutofillClient::MenuItemIDPasswordEntry: 221 case WebAutofillClient::MenuItemIDPasswordEntry:
212 case WebAutofillClient::MenuItemIDDataListEntry: 222 // User selected an Autocomplete or password entry, so we fill directly.
213 // User selected an Autocomplete or password or datalist entry, so we
214 // fill directly.
215 SetNodeText(value, &element_); 223 SetNodeText(value, &element_);
216 break; 224 break;
225 case WebAutofillClient::MenuItemIDDataListEntry: {
226 string16 new_value = value;
227 // If this element takes multiple values then replace the last part with
228 // the suggestion.
229 if (element_.isMultiple() &&
230 element_.formControlType() == WebString::fromUTF8("email")) {
231 std::vector<string16> parts;
232
233 base::SplitStringDontTrim(element_.editingValue(), ',', &parts);
234 if (parts.size() == 0)
235 parts.push_back(string16());
236
237 string16 last_part = parts.back();
238 // We want to keep just the leading whitespace.
239 for (size_t i = 0; i < last_part.size(); ++i) {
240 if (!IsWhitespace(last_part[i])) {
241 last_part = last_part.substr(0, i);
242 break;
243 }
244 }
245 last_part.append(value);
246 parts[parts.size() - 1] = last_part;
247
248 new_value = JoinString(parts, ',');
249 }
250 SetNodeText(new_value, &element_);
251 break;
252 }
Ilya Sherman 2012/05/15 21:12:39 nit: Please decompose this block to a helper metho
keishi 2012/05/16 11:44:07 Done.
217 default: 253 default:
218 // A positive item_id is a unique id for an autofill (vs. autocomplete) 254 // A positive item_id is a unique id for an autofill (vs. autocomplete)
219 // suggestion. 255 // suggestion.
220 DCHECK_GT(item_id, 0); 256 DCHECK_GT(item_id, 0);
221 // Fill the values for the whole form. 257 // Fill the values for the whole form.
222 FillAutofillFormData(node, item_id, AUTOFILL_FILL); 258 FillAutofillFormData(node, item_id, AUTOFILL_FILL);
223 } 259 }
224 } 260 }
225 261
226 void AutofillAgent::didSelectAutofillSuggestion(const WebNode& node, 262 void AutofillAgent::didSelectAutofillSuggestion(const WebNode& node,
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 void AutofillAgent::ShowSuggestions(const WebInputElement& element, 531 void AutofillAgent::ShowSuggestions(const WebInputElement& element,
496 bool autofill_on_empty_values, 532 bool autofill_on_empty_values,
497 bool requires_caret_at_end, 533 bool requires_caret_at_end,
498 bool display_warning_if_disabled) { 534 bool display_warning_if_disabled) {
499 if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() || 535 if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() ||
500 element.isPasswordField() || !element.suggestedValue().isEmpty()) 536 element.isPasswordField() || !element.suggestedValue().isEmpty())
501 return; 537 return;
502 538
503 // Don't attempt to autofill with values that are too large or if filling 539 // Don't attempt to autofill with values that are too large or if filling
504 // criteria are not met. 540 // criteria are not met.
505 WebString value = element.value(); 541 WebString value = element.editingValue();
506 if (value.length() > kMaximumTextSizeForAutofill || 542 if (value.length() > kMaximumTextSizeForAutofill ||
507 (!autofill_on_empty_values && value.isEmpty()) || 543 (!autofill_on_empty_values && value.isEmpty()) ||
508 (requires_caret_at_end && 544 (requires_caret_at_end &&
509 (element.selectionStart() != element.selectionEnd() || 545 (element.selectionStart() != element.selectionEnd() ||
510 element.selectionEnd() != static_cast<int>(value.length())))) { 546 element.selectionEnd() != static_cast<int>(value.length())))) {
511 // Any popup currently showing is obsolete. 547 // Any popup currently showing is obsolete.
512 WebKit::WebView* web_view = render_view()->GetWebView(); 548 WebKit::WebView* web_view = render_view()->GetWebView();
513 if (web_view) 549 if (web_view)
514 web_view->hidePopups(); 550 web_view->hidePopups();
515 551
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 autofill_action_ = action; 615 autofill_action_ = action;
580 Send(new AutofillHostMsg_FillAutofillFormData( 616 Send(new AutofillHostMsg_FillAutofillFormData(
581 routing_id(), autofill_query_id_, form, field, unique_id)); 617 routing_id(), autofill_query_id_, form, field, unique_id));
582 } 618 }
583 619
584 void AutofillAgent::SetNodeText(const string16& value, 620 void AutofillAgent::SetNodeText(const string16& value,
585 WebKit::WebInputElement* node) { 621 WebKit::WebInputElement* node) {
586 string16 substring = value; 622 string16 substring = value;
587 substring = substring.substr(0, node->maxLength()); 623 substring = substring.substr(0, node->maxLength());
588 624
589 node->setValue(substring, true); 625 WebKit::WebView* web_view = render_view()->GetWebView();
626 if (!web_view || !web_view->focusedFrame())
627 return;
Ilya Sherman 2012/05/15 21:12:39 nit: Is this code still needed? If so, please add
keishi 2012/05/16 11:44:07 Done.
628
629 node->setEditingValue(substring);
590 } 630 }
591 631
592 } // namespace autofill 632 } // namespace autofill
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698