Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / autofill / content / renderer / autofill_agent.cc
index d6dbfa1..80326c3 100644 (file)
 #include "net/cert/cert_status_flags.h"
 #include "third_party/WebKit/public/platform/WebRect.h"
 #include "third_party/WebKit/public/platform/WebURLRequest.h"
+#include "third_party/WebKit/public/web/WebConsoleMessage.h"
 #include "third_party/WebKit/public/web/WebDataSource.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebElementCollection.h"
 #include "third_party/WebKit/public/web/WebFormControlElement.h"
 #include "third_party/WebKit/public/web/WebFormElement.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebNode.h"
 #include "third_party/WebKit/public/web/WebOptionElement.h"
 #include "third_party/WebKit/public/web/WebTextAreaElement.h"
@@ -47,6 +48,7 @@
 #include "ui/events/keycodes/keyboard_codes.h"
 
 using blink::WebAutofillClient;
+using blink::WebConsoleMessage;
 using blink::WebElement;
 using blink::WebElementCollection;
 using blink::WebFormControlElement;
@@ -54,6 +56,7 @@ using blink::WebFormElement;
 using blink::WebFrame;
 using blink::WebInputElement;
 using blink::WebKeyboardEvent;
+using blink::WebLocalFrame;
 using blink::WebNode;
 using blink::WebOptionElement;
 using blink::WebString;
@@ -166,7 +169,7 @@ bool AutofillAgent::OnMessageReceived(const IPC::Message& message) {
   return handled;
 }
 
-void AutofillAgent::DidFinishDocumentLoad(WebFrame* frame) {
+void AutofillAgent::DidFinishDocumentLoad(WebLocalFrame* frame) {
   // Record timestamp on document load. This is used to record overhead of
   // Autofill feature.
   forms_seen_timestamp_ = base::TimeTicks::Now();
@@ -211,7 +214,7 @@ void AutofillAgent::FrameWillClose(WebFrame* frame) {
   }
 }
 
-void AutofillAgent::WillSubmitForm(WebFrame* frame,
+void AutofillAgent::WillSubmitForm(WebLocalFrame* frame,
                                    const WebFormElement& form) {
   FormData form_data;
   if (WebFormElementToFormData(form,
@@ -234,6 +237,12 @@ void AutofillAgent::ZoomLevelChanged() {
 }
 
 void AutofillAgent::FocusedNodeChanged(const WebNode& node) {
+  if (password_generation_agent_ &&
+      password_generation_agent_->FocusedNodeHasChanged(node)) {
+    is_popup_possibly_visible_ = true;
+    return;
+  }
+
   if (node.isNull() || !node.isElementNode())
     return;
 
@@ -251,36 +260,52 @@ void AutofillAgent::FocusedNodeChanged(const WebNode& node) {
   element_ = *element;
 }
 
-void AutofillAgent::OrientationChangeEvent(int orientation) {
+void AutofillAgent::OrientationChangeEvent() {
   HidePopup();
 }
 
-void AutofillAgent::DidChangeScrollOffset(WebFrame*) {
+void AutofillAgent::DidChangeScrollOffset(WebLocalFrame*) {
   HidePopup();
 }
 
-void AutofillAgent::didRequestAutocomplete(WebFrame* frame,
-                                           const WebFormElement& form) {
+void AutofillAgent::didRequestAutocomplete(
+    const WebFormElement& form,
+    const blink::WebAutocompleteParams& details) {
+  // TODO(estade): honor |details|.
+
   // Disallow the dialog over non-https or broken https, except when the
   // ignore SSL flag is passed. See http://crbug.com/272512.
   // TODO(palmer): this should be moved to the browser process after frames
   // get their own processes.
-  GURL url(frame->document().url());
-  content::SSLStatus ssl_status = render_view()->GetSSLStatusOfFrame(frame);
-  bool is_safe = url.SchemeIs(content::kHttpsScheme) &&
+  GURL url(form.document().url());
+  content::SSLStatus ssl_status =
+      render_view()->GetSSLStatusOfFrame(form.document().frame());
+  bool is_safe = url.SchemeIs(url::kHttpsScheme) &&
       !net::IsCertStatusError(ssl_status.cert_status);
   bool allow_unsafe = CommandLine::ForCurrentProcess()->HasSwitch(
       ::switches::kReduceSecurityForTesting);
 
   FormData form_data;
-  if (!in_flight_request_form_.isNull() ||
-      (!is_safe && !allow_unsafe) ||
-      !WebFormElementToFormData(form,
-                                WebFormControlElement(),
-                                REQUIRE_AUTOCOMPLETE,
-                                EXTRACT_OPTIONS,
-                                &form_data,
-                                NULL)) {
+  std::string error_message;
+  if (!in_flight_request_form_.isNull()) {
+    error_message = "already active.";
+  } else if (!is_safe && !allow_unsafe) {
+    error_message =
+        "must use a secure connection or --reduce-security-for-testing.";
+  } else if (!WebFormElementToFormData(form,
+                                       WebFormControlElement(),
+                                       REQUIRE_AUTOCOMPLETE,
+                                       EXTRACT_OPTIONS,
+                                       &form_data,
+                                       NULL)) {
+    error_message = "failed to parse form.";
+  }
+
+  if (!error_message.empty()) {
+    WebConsoleMessage console_message = WebConsoleMessage(
+        WebConsoleMessage::LevelLog,
+        WebString(base::ASCIIToUTF16("requestAutocomplete: ") +
+                      base::ASCIIToUTF16(error_message)));
     WebFormElement(form).finishRequestAutocomplete(
         WebFormElement::AutocompleteResultErrorDisabled);
     return;
@@ -352,6 +377,7 @@ void AutofillAgent::TextFieldDidChangeImpl(
   if (input_element) {
     if (password_generation_agent_ &&
         password_generation_agent_->TextDidChangeInTextField(*input_element)) {
+      is_popup_possibly_visible_ = true;
       return;
     }
 
@@ -390,6 +416,10 @@ void AutofillAgent::openTextDataListChooser(const WebInputElement& element) {
     ShowSuggestions(element, true, false, false, true);
 }
 
+void AutofillAgent::firstUserGestureObserved() {
+  password_autofill_agent_->FirstUserGestureObserved();
+}
+
 void AutofillAgent::AcceptDataListSuggestion(
     const base::string16& suggested_value) {
   WebInputElement* input_element = toWebInputElement(&element_);
@@ -484,29 +514,38 @@ void AutofillAgent::OnAcceptDataListSuggestion(const base::string16& value) {
 }
 
 void AutofillAgent::OnAcceptPasswordAutofillSuggestion(
-    const base::string16& username) {
-  // We need to make sure this is handled here because the browser process
-  // skipped it handling because it believed it would be handled here. If it
-  // isn't handled here then the browser logic needs to be updated.
-  bool handled = password_autofill_agent_->DidAcceptAutofillSuggestion(
+    const base::string16& username,
+    const base::string16& password) {
+  bool handled = password_autofill_agent_->AcceptSuggestion(
       element_,
-      username);
+      username,
+      password);
   DCHECK(handled);
 }
 
 void AutofillAgent::OnRequestAutocompleteResult(
     WebFormElement::AutocompleteResult result,
+    const base::string16& message,
     const FormData& form_data) {
   if (in_flight_request_form_.isNull())
     return;
 
   if (result == WebFormElement::AutocompleteResultSuccess) {
     FillFormIncludingNonFocusableElements(form_data, in_flight_request_form_);
-    if (!in_flight_request_form_.checkValidityWithoutDispatchingEvents())
+    if (!in_flight_request_form_.checkValidity())
       result = WebFormElement::AutocompleteResultErrorInvalid;
   }
 
   in_flight_request_form_.finishRequestAutocomplete(result);
+
+  if (!message.empty()) {
+    const base::string16 prefix(base::ASCIIToUTF16("requestAutocomplete: "));
+    WebConsoleMessage console_message = WebConsoleMessage(
+        WebConsoleMessage::LevelLog, WebString(prefix + message));
+    in_flight_request_form_.document().frame()->addMessageToConsole(
+        console_message);
+  }
+
   in_flight_request_form_.reset();
 }
 
@@ -601,24 +640,24 @@ void AutofillAgent::QueryAutofillSuggestions(
   gfx::RectF bounding_box_scaled =
       GetScaledBoundingBox(web_view_->pageScaleFactor(), &element_);
 
+  std::vector<base::string16> data_list_values;
+  std::vector<base::string16> data_list_labels;
   const WebInputElement* input_element = toWebInputElement(&element);
   if (input_element) {
     // Find the datalist values and send them to the browser process.
-    std::vector<base::string16> data_list_values;
-    std::vector<base::string16> data_list_labels;
     GetDataListSuggestions(*input_element,
                            datalist_only,
                            &data_list_values,
                            &data_list_labels);
     TrimStringVectorForIPC(&data_list_values);
     TrimStringVectorForIPC(&data_list_labels);
-
-    Send(new AutofillHostMsg_SetDataList(routing_id(),
-                                         data_list_values,
-                                         data_list_labels));
   }
 
   is_popup_possibly_visible_ = true;
+  Send(new AutofillHostMsg_SetDataList(routing_id(),
+                                       data_list_values,
+                                       data_list_labels));
+
   Send(new AutofillHostMsg_QueryFormFieldAutofill(routing_id(),
                                                   autofill_query_id_,
                                                   form,