summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-09-13 10:40:13 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-09-13 10:40:13 -0700
commit9149fda254e7ff835dfcd93d8d7a5b3521a788d9 (patch)
tree86e789709760d6a28457f42798bef401e246793a
parent43df208144c6a77abc560712195027cbc13ce9de (diff)
parentd0fc68897b5a7379951aaa5d50f0802dbe9e00d4 (diff)
downloadexternal_webkit-9149fda254e7ff835dfcd93d8d7a5b3521a788d9.zip
external_webkit-9149fda254e7ff835dfcd93d8d7a5b3521a788d9.tar.gz
external_webkit-9149fda254e7ff835dfcd93d8d7a5b3521a788d9.tar.bz2
Merge "Initial autofill changes in libwebcore."
-rw-r--r--Android.mk41
-rw-r--r--WebCore/Android.derived.mk48
-rw-r--r--WebKit/Android.mk11
-rw-r--r--WebKit/android/WebCoreSupport/ChromiumIncludes.h16
-rw-r--r--WebKit/android/WebCoreSupport/EditorClientAndroid.cpp27
-rw-r--r--WebKit/android/WebCoreSupport/EditorClientAndroid.h12
-rw-r--r--WebKit/android/WebCoreSupport/WebRequestContext.cpp4
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.h6
-rw-r--r--WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.cpp50
-rw-r--r--WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.h54
-rw-r--r--WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.cpp80
-rw-r--r--WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.h100
-rw-r--r--WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.cpp637
-rw-r--r--WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.h163
-rw-r--r--WebKit/android/WebCoreSupport/autofill/MainThreadProxy.cpp35
-rw-r--r--WebKit/android/WebCoreSupport/autofill/MainThreadProxy.h37
-rw-r--r--WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp125
-rw-r--r--WebKit/android/WebCoreSupport/autofill/WebAutoFill.h80
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp11
19 files changed, 1533 insertions, 4 deletions
diff --git a/Android.mk b/Android.mk
index f7af340..a464425 100644
--- a/Android.mk
+++ b/Android.mk
@@ -101,6 +101,20 @@ ifneq ($(HTTP_STACK),chrome)
endif
endif
+# Read the environment variable to determine if Autofill is enabled.
+# The default is off. Chrome HTTP stack must be used when Autofill
+# is turned on.
+
+ifneq ($(ENABLE_AUTOFILL),true)
+ ENABLE_AUTOFILL=false
+endif
+
+ifneq ($(HTTP_STACK),chrome)
+ ifeq ($(ENABLE_AUTOFILL),true)
+ ENABLE_AUTOFILL = false
+ endif
+endif
+
BASE_PATH := $(call my-dir)
include $(CLEAR_VARS)
@@ -218,6 +232,16 @@ LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) \
$(base_intermediates)/WebCore/html \
$(base_intermediates)/WebCore/platform
+# The following includes are needed by the AutoFill feature.
+LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) \
+ $(LOCAL_PATH)/WebKit/chromium \
+ $(LOCAL_PATH)/WebKit/chromium/public \
+ external/chromium/chrome/browser \
+ external/chromium/chrome/renderer \
+ external/chromium/android \
+ external/chromium/chrome \
+ external/skia
+
ifeq ($(JAVASCRIPT_ENGINE),v8)
# Include WTF source file.
d := JavaScriptCore
@@ -364,6 +388,10 @@ LOCAL_STATIC_LIBRARIES += libchromium_net
LOCAL_SHARED_LIBRARIES += libcrypto libssl libz
endif # HTTP_STACK == chrome
+ifeq ($(ENABLE_AUTOFILL),true)
+LOCAL_SHARED_LIBRARIES += libexpat
+endif
+
# Redefine LOCAL_SRC_FILES to be all the WebKit source files
LOCAL_SRC_FILES := $(WEBKIT_SRC_FILES)
@@ -428,6 +456,19 @@ LOCAL_C_INCLUDES := $(WEBKIT_C_INCLUDES)
LOCAL_PATH := $(BASE_PATH)
LOCAL_SRC_FILES := \
WebKit/android/jni/WebCoreJniOnLoad.cpp
+
+ifeq ($(ENABLE_AUTOFILL),true)
+# AutoFill requires some cpp files from Chromium to link with
+# libchromium_net. We cannot compile them into libchromium_net
+# because they have cpp file extensions, not .cc.
+LOCAL_CFLAGS += -DWEBKIT_IMPLEMENTATION=1
+LOCAL_SRC_FILES += \
+ WebKit/android/WebCoreSupport/autofill/MainThreadProxy.cpp \
+ WebKit/chromium/src/WebCString.cpp \
+ WebKit/chromium/src/WebRegularExpression.cpp \
+ WebKit/chromium/src/WebString.cpp
+endif
+
# Do this dependency by hand. The reason we have to do this is because the
# headers that this file pulls in are generated during the build of webcore.
# We make all of our object files depend on those files so that they are built
diff --git a/WebCore/Android.derived.mk b/WebCore/Android.derived.mk
index e913a48..e2cf096 100644
--- a/WebCore/Android.derived.mk
+++ b/WebCore/Android.derived.mk
@@ -176,3 +176,51 @@ $(GEN): xlink_attrs := $(LOCAL_PATH)/svg/xlinkattrs.in
$(GEN): $(LOCAL_PATH)/dom/make_names.pl $(xlink_attrs)
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
+
+ifeq ($(ENABLE_AUTOFILL),true)
+# This is really ugly, but necessary. The following rules are taken from
+# external/chromium/Android.mk.
+# Chromium uses several third party libraries and headers that are already
+# present on Android, but in different include paths. Generate a set of
+# forwarding headers in the location that Chromium expects. We need to do
+# this in both the Chromium and WebCore projects because of the
+# WebKit <-> Chromium bindings which include headers from the Chromuim project.
+
+THIRD_PARTY = $(intermediates)/third_party
+CHROMIUM_SRC_DIR := $(LOCAL_PATH)/../../chromium
+SCRIPT := $(CHROMIUM_SRC_DIR)/android/generateAndroidForwardingHeader.pl
+
+GEN := $(THIRD_PARTY)/expat/files/lib/expat.h
+$(GEN): $(SCRIPT)
+$(GEN):
+ perl $(SCRIPT) $@ "lib/expat.h"
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+GEN := $(THIRD_PARTY)/skia/include/core/SkBitmap.h
+$(GEN): $(SCRIPT)
+$(GEN):
+ perl $(SCRIPT) $@ "include/core/SkBitmap.h"
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+GEN := $(THIRD_PARTY)/WebKit/WebKit/chromium/public/WebFormControlElement.h
+$(GEN): $(SCRIPT)
+$(GEN):
+ perl $(SCRIPT) $@ "public/WebFormControlElement.h"
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+GEN := $(THIRD_PARTY)/WebKit/WebKit/chromium/public/WebRegularExpression.h
+$(GEN): $(SCRIPT)
+$(GEN):
+ perl $(SCRIPT) $@ "public/WebRegularExpression.h"
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+GEN := $(THIRD_PARTY)/WebKit/WebKit/chromium/public/WebString.h
+$(GEN): $(SCRIPT)
+$(GEN):
+ perl $(SCRIPT) $@ "public/WebString.h"
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+endif
+
+LOCAL_SRC_FILES += $(LOCAL_GENERATED_SOURCES)
+
diff --git a/WebKit/Android.mk b/WebKit/Android.mk
index 01ede0f..a361974 100644
--- a/WebKit/Android.mk
+++ b/WebKit/Android.mk
@@ -106,3 +106,14 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
android/wds/Command.cpp \
android/wds/Connection.cpp \
android/wds/DebugServer.cpp
+
+# Needed for autofill.
+ifeq ($(ENABLE_AUTOFILL),true)
+LOCAL_CFLAGS += -DENABLE_WEB_AUTOFILL
+
+LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
+ android/WebCoreSupport/autofill/AutoFillHostAndroid.cpp \
+ android/WebCoreSupport/autofill/FormFieldAndroid.cpp \
+ android/WebCoreSupport/autofill/FormManagerAndroid.cpp \
+ android/WebCoreSupport/autofill/WebAutoFill.cpp
+endif # ENABLE_AUTOFILL == true
diff --git a/WebKit/android/WebCoreSupport/ChromiumIncludes.h b/WebKit/android/WebCoreSupport/ChromiumIncludes.h
index a7abef1..1a69ff1 100644
--- a/WebKit/android/WebCoreSupport/ChromiumIncludes.h
+++ b/WebKit/android/WebCoreSupport/ChromiumIncludes.h
@@ -26,6 +26,8 @@
#ifndef ChromiumIncludes_h
#define ChromiumIncludes_h
+#include "config.h"
+
// Include all external/chromium files in this file so the problems with the LOG
// and LOG_ASSERT defines can be handled in one place.
@@ -64,6 +66,20 @@
#include <net/url_request/url_request.h>
#include <net/url_request/url_request_context.h>
+#if ENABLE(WEB_AUTOFILL)
+#include <autofill/autofill_manager.h>
+#include <autofill/autofill_profile.h>
+#include <autofill/personal_data_manager.h>
+#include <base/logging.h>
+#include <base/scoped_vector.h>
+#include <base/string16.h>
+#include <base/utf_string_conversions.h>
+#include <chrome/browser/autofill/autofill_host.h>
+#include <chrome/browser/profile.h>
+#include <chrome/browser/tab_contents/tab_contents.h>
+#include <webkit/glue/form_data.h>
+#endif
+
#undef LOG
#if defined(LOG_WAS_DEFINED) && defined(LOG_PRI)
#define LOG(priority, tag, ...) LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
diff --git a/WebKit/android/WebCoreSupport/EditorClientAndroid.cpp b/WebKit/android/WebCoreSupport/EditorClientAndroid.cpp
index 45498c0..f5f8211 100644
--- a/WebKit/android/WebCoreSupport/EditorClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/EditorClientAndroid.cpp
@@ -32,6 +32,7 @@
#include "EventNames.h"
#include "FocusController.h"
#include "Frame.h"
+#include "HTMLNames.h"
#include "KeyboardEvent.h"
#include "NotImplemented.h"
#include "PlatformKeyboardEvent.h"
@@ -39,6 +40,8 @@
#include "WebViewCore.h"
#include "WindowsKeyboardCodes.h"
+using namespace WebCore::HTMLNames;
+
namespace android {
void EditorClientAndroid::pageDestroyed() {
@@ -235,6 +238,19 @@ void EditorClientAndroid::respondToChangedSelection() {
Frame* frame = m_page->focusController()->focusedOrMainFrame();
if (!frame || !frame->view())
return;
+
+#if ENABLE(WEB_AUTOFILL)
+ WebCore::Node* focusedNode = frame->document()->focusedNode();
+ if (focusedNode && focusedNode->hasTagName(inputTag)) {
+ WebCore::HTMLInputElement* element = static_cast<WebCore::HTMLInputElement*>(focusedNode);
+ // TODO: If it's a text field, inform AutoFill that it should get AutoFill suggestions for
+ // the form it belongs to. AutoFill can also work with select-one elements (i.e. <select>
+ // without the "multiple" attribute set. Is it safe to call this function with select elements?
+ // How should AutoFill communicate select suggestions to Java?
+ if (element->isTextField())
+ m_autoFill->formFieldFocused(static_cast<HTMLFormControlElement*>(focusedNode));
+ }
+#endif
WebViewCore* webViewCore = WebViewCore::getWebViewCore(frame->view());
webViewCore->updateTextSelection();
}
@@ -261,4 +277,15 @@ void EditorClientAndroid::willSetInputMethodState()
{
notImplemented();
}
+
+#if ENABLE(WEB_AUTOFILL)
+WebAutoFill* EditorClientAndroid::getAutoFill()
+{
+ if (!m_autoFill)
+ m_autoFill.set(new WebAutoFill());
+
+ return m_autoFill.get();
+}
+#endif
+
}
diff --git a/WebKit/android/WebCoreSupport/EditorClientAndroid.h b/WebKit/android/WebCoreSupport/EditorClientAndroid.h
index 6d49f48..9aed88c 100644
--- a/WebKit/android/WebCoreSupport/EditorClientAndroid.h
+++ b/WebKit/android/WebCoreSupport/EditorClientAndroid.h
@@ -26,8 +26,14 @@
#ifndef EditorClientAndroid_h
#define EditorClientAndroid_h
+#include "config.h"
+
+
#include "EditorClient.h"
#include "Page.h"
+#include "autofill/WebAutoFill.h"
+
+#include <wtf/OwnPtr.h>
using namespace WebCore;
@@ -111,10 +117,16 @@ public:
void setPage(Page* page) { m_page = page; }
void setShouldChangeSelectedRange(bool shouldChangeSelectedRange) { m_shouldChangeSelectedRange = shouldChangeSelectedRange; }
void setUiGeneratedSelectionChange(bool uiGenerated) { m_uiGeneratedSelectionChange = uiGenerated; }
+#if ENABLE(WEB_AUTOFILL)
+ WebAutoFill* getAutoFill();
+#endif
private:
Page* m_page;
bool m_shouldChangeSelectedRange;
bool m_uiGeneratedSelectionChange;
+#if ENABLE(WEB_AUTOFILL)
+ OwnPtr<WebAutoFill> m_autoFill;
+#endif
};
}
diff --git a/WebKit/android/WebCoreSupport/WebRequestContext.cpp b/WebKit/android/WebCoreSupport/WebRequestContext.cpp
index dc9feae..0dda816 100644
--- a/WebKit/android/WebCoreSupport/WebRequestContext.cpp
+++ b/WebKit/android/WebCoreSupport/WebRequestContext.cpp
@@ -28,6 +28,7 @@
#include "WebRequestContext.h"
#include "JNIUtility.h"
+#include "WebUrlLoaderClient.h"
#include "jni.h"
#include <dirent.h>
#include <sys/types.h>
@@ -121,7 +122,8 @@ scoped_refptr<WebRequestContext> WebRequestContext::GetAndroidContextForPath(con
scoped_refptr<WebRequestContext> androidContext = new WebRequestContext();
androidContext->host_resolver_ = net::CreateSystemHostResolver(0);
- scoped_refptr<base::MessageLoopProxy> cacheMessageLoopProxy = base::MessageLoopProxy::CreateForCurrentThread();
+ base::Thread* ioThread = WebUrlLoaderClient::ioThread();
+ scoped_refptr<base::MessageLoopProxy> cacheMessageLoopProxy = ioThread->message_loop_proxy();
// Todo: check if the context takes ownership of the cache
net::HttpCache::DefaultBackend* defaultBackend = new net::HttpCache::DefaultBackend(net::DISK_CACHE, cachePath, 20 * 1024 * 1024, cacheMessageLoopProxy);
androidContext->http_transaction_factory_ = new net::HttpCache(androidContext->host_resolver(), net::ProxyService::CreateNull(), net::SSLConfigService::CreateSystemSSLConfigService(), net::HttpAuthHandlerFactory::CreateDefault(), 0, 0, defaultBackend);
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
index 1a8118c..92c7bb5 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
@@ -83,6 +83,9 @@ public:
static void didFail(void*);
static void willSendRequest(void*);
+ // Handle to the chrome IO thread
+ static base::Thread* ioThread();
+
private:
void finish();
RefPtr<WebCore::ResourceHandle> m_resourceHandle;
@@ -93,9 +96,6 @@ private:
// Not an OwnPtr since it should be deleted on another thread
WebRequest* m_request;
- // Handle to the chrome IO thread
- static base::Thread* ioThread();
-
// Check if a request is active
bool isActive() const;
diff --git a/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.cpp b/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.cpp
new file mode 100644
index 0000000..51f7a93
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AutoFillHostAndroid.h"
+
+#include "autofill/WebAutoFill.h"
+
+namespace android {
+
+AutoFillHostAndroid::AutoFillHostAndroid(WebAutoFill* autoFill)
+ : mAutoFill(autoFill)
+{
+}
+
+void AutoFillHostAndroid::AutoFillSuggestionsReturned(int queryId, const std::vector<string16>& names, const std::vector<string16>& labels, const std::vector<int>& uniqueIds)
+{
+ if (mAutoFill)
+ mAutoFill->fillFormFields(queryId, names[0], labels[0], uniqueIds[0]);
+}
+
+void AutoFillHostAndroid::AutoFillFormDataFilled(int queryId, const webkit_glue::FormData& form)
+{
+ if (mAutoFill)
+ mAutoFill->fillFormInPage(queryId, form);
+}
+
+}
diff --git a/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.h b/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.h
new file mode 100644
index 0000000..1984098
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/autofill/AutoFillHostAndroid.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AutoFillHostAndroid_h
+#define AutoFillHostAndroid_h
+
+#include "ChromiumIncludes.h"
+
+#include <vector>
+
+namespace webkit_glue {
+class FormData;
+}
+
+namespace android {
+class WebAutoFill;
+
+// This class receives the callbacks from the AutoFillManager in the Chromium code.
+class AutoFillHostAndroid : public AutoFillHost {
+public:
+ AutoFillHostAndroid(WebAutoFill* autoFill);
+ virtual ~AutoFillHostAndroid() { }
+
+ virtual void AutoFillSuggestionsReturned(int queryId, const std::vector<string16>& names, const std::vector<string16>& labels, const std::vector<int>& uniqueIds);
+ virtual void AutoFillFormDataFilled(int queryId, const webkit_glue::FormData&);
+
+private:
+ WebAutoFill* mAutoFill;
+};
+}
+
+#endif
diff --git a/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.cpp b/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.cpp
new file mode 100644
index 0000000..00213a1
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved.
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FormFieldAndroid.h"
+
+#include "ChromiumIncludes.h"
+#include "HTMLFormControlElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLSelectElement.h"
+
+// TODO: This file is taken from chromium/webkit/glue/form_field.h and
+// customised to use WebCore types rather than WebKit API types. It would
+// be nice and would ease future merge pain if the two could be combined.
+
+namespace webkit_glue {
+FormField::FormField()
+ : size_(0) {
+}
+
+FormField::FormField(WebCore::HTMLFormControlElement& element)
+ : size_(0) {
+ name_ = string16(element.name().characters());
+
+ // TODO: Extract the field label. For now we just use the field
+ // name.
+ label_ = name_;
+
+ form_control_type_ = string16(element.type().characters());
+ if (form_control_type_ == ASCIIToUTF16("text")) {
+ WebCore::HTMLInputElement* input_element = static_cast<WebCore::HTMLInputElement*>(&element);
+ value_ = string16(input_element->value().characters());
+ size_ = input_element->size();
+ } else if (form_control_type_ == ASCIIToUTF16("select-one")) {
+ WebCore::HTMLSelectElement* select_element = static_cast<WebCore::HTMLSelectElement*>(&element);
+ value_ = string16(select_element->value().characters());
+ }
+
+ TrimWhitespace(value_, TRIM_LEADING, &value_);
+}
+
+FormField::FormField(const string16& label,
+ const string16& name,
+ const string16& value,
+ const string16& form_control_type,
+ int size)
+ : label_(label),
+ name_(name),
+ value_(value),
+ form_control_type_(form_control_type),
+ size_(size) {
+}
+
+bool FormField::operator!=(const FormField& field) const {
+ return !operator==(field);
+}
+} // namespace webkit_glue
diff --git a/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.h b/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.h
new file mode 100644
index 0000000..51bb24b
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/autofill/FormFieldAndroid.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved.
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FormFieldAndroid_h
+#define FormFieldAndroid_h
+
+#include <base/string16.h>
+#include <vector>
+
+// TODO: This file is taken from chromium/webkit/glue/form_field.cc and
+// customised to use WebCore types rather than WebKit API types. It would
+// be nice and would ease future merge pain if the two could be combined.
+
+namespace WebCore {
+class HTMLFormControlElement;
+}
+
+namespace webkit_glue {
+
+// Stores information about a field in a form.
+class FormField {
+public:
+ FormField();
+ explicit FormField(WebCore::HTMLFormControlElement& element);
+ FormField(const string16& label,
+ const string16& name,
+ const string16& value,
+ const string16& form_control_type,
+ int size);
+
+ const string16& label() const { return label_; }
+ const string16& name() const { return name_; }
+ const string16& value() const { return value_; }
+ const string16& form_control_type() const { return form_control_type_; }
+ int size() const { return size_; }
+ // Returns option string for elements for which they make sense (select-one,
+ // for example) for the rest of elements return an empty array.
+ const std::vector<string16>& option_strings() const {
+ return option_strings_;
+ }
+
+
+ void set_label(const string16& label) { label_ = label; }
+ void set_name(const string16& name) { name_ = name; }
+ void set_value(const string16& value) { value_ = value; }
+ void set_form_control_type(const string16& form_control_type) {
+ form_control_type_ = form_control_type;
+ }
+ void set_size(int size) { size_ = size; }
+ void set_option_strings(const std::vector<string16>& strings) {
+ option_strings_ = strings;
+ }
+
+ bool operator==(const FormField& field) const;
+ bool operator!=(const FormField& field) const;
+
+private:
+ string16 label_;
+ string16 name_;
+ string16 value_;
+ string16 form_control_type_;
+ int size_;
+ std::vector<string16> option_strings_;
+};
+
+inline bool FormField::operator==(const FormField& field) const {
+ // A FormField stores a value, but the value is not part of the identity of
+ // the field, so we don't want to compare the values.
+ return (label_ == field.label_ &&
+ name_ == field.name_ &&
+ form_control_type_ == field.form_control_type_);
+
+}
+
+} // namespace webkit_glue
+
+#endif // WEBKIT_GLUE_FORM_FIELD_H_
diff --git a/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.cpp b/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.cpp
new file mode 100644
index 0000000..c97a2a8
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.cpp
@@ -0,0 +1,637 @@
+/*
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved.
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FormManagerAndroid.h"
+
+#include "HTMLFormControlElement.h"
+#include "HTMLFormElement.h"
+#include "HTMLTextAreaElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLLabelElement.h"
+#include "HTMLNames.h"
+#include "HTMLSelectElement.h"
+#include "NodeList.h"
+#include "HTMLCollection.h"
+#include "FormFieldAndroid.h"
+#include "QualifiedName.h"
+
+
+// TODO: This file is taken from chromium/chrome/renderer/form_manager.cc and
+// customised to use WebCore types rather than WebKit API types. It would be
+// nice and would ease future merge pain if the two could be combined.
+
+using webkit_glue::FormData;
+using webkit_glue::FormField;
+using WebCore::HTMLElement;
+using WebCore::HTMLFormControlElement;
+using WebCore::HTMLFormElement;
+using WebCore::HTMLLabelElement;
+using WebCore::HTMLSelectElement;
+using WebCore::Node;
+using WebCore::NodeList;
+
+using namespace WebCore::HTMLNames;
+
+namespace {
+
+// The number of fields required by AutoFill. Ideally we could send the forms
+// to AutoFill no matter how many fields are in the forms; however, finding the
+// label for each field is a costly operation and we can't spare the cycles if
+// it's not necessary.
+// Note the on ANDROID we reduce this from Chromium's 3 as it allows us to
+// autofill simple name/email forms for example. This improves the mobile
+// device experience where form filling can be time consuming and frustrating.
+const size_t kRequiredAutoFillFields = 2;
+
+string16 WTFStringToString16(const WTF::String& wtfString)
+{
+ WTF::String str = wtfString;
+
+ if (str.charactersWithNullTermination())
+ return string16(str.charactersWithNullTermination());
+ else
+ return string16();
+}
+
+string16 S(const WTF::AtomicString& str)
+{
+ return WTFStringToString16(str.string());
+}
+
+string16 S(const WTF::String& string)
+{
+ return WTFStringToString16(string);
+}
+
+// This is a helper function for the FindChildText() function.
+// Returns the node value of the descendant or sibling of |node| that is a
+// non-empty text node. This is a faster alternative to |innerText()| for
+// performance critical operations. It does a full depth-first search so
+// can be used when the structure is not directly known. It does not aggregate
+// the text of multiple nodes, it just returns the value of the first found.
+// "Non-empty" in this case means non-empty after the whitespace has been
+// stripped.
+string16 FindChildTextInner(const Node* node) {
+ string16 element_text;
+ if (!node)
+ return element_text;
+
+ element_text = S(node->nodeValue());
+ TrimWhitespace(element_text, TRIM_ALL, &element_text);
+ if (!element_text.empty())
+ return element_text;
+
+ element_text = FindChildTextInner(node->firstChild());
+ if (!element_text.empty())
+ return element_text;
+
+ element_text = FindChildTextInner(node->nextSibling());
+ if (!element_text.empty())
+ return element_text;
+
+ return element_text;
+}
+
+// Returns the node value of the first decendant of |element| that is a
+// non-empty text node. "Non-empty" in this case means non-empty after the
+// whitespace has been stripped.
+string16 FindChildText(const HTMLElement* element) {
+ Node* child = element->firstChild();
+ return FindChildTextInner(child);
+}
+
+} // namespace
+
+namespace android {
+
+FormManager::FormManager() {
+}
+
+FormManager::~FormManager() {
+ Reset();
+}
+
+// static
+void FormManager::HTMLFormControlElementToFormField(
+ const HTMLFormControlElement& element, bool get_value, FormField* field) {
+ ASSERT(field);
+
+ // The label is not officially part of a HTMLFormControlElement; however, the
+ // labels for all form control elements are scraped from the DOM and set in
+ // WebFormElementToFormData.
+ field->set_name(S(element.name()));
+ field->set_form_control_type(S(element.type()));
+
+ if (!get_value)
+ return;
+
+ string16 value;
+ if (element.type() == WTF::AtomicString("text")) {
+ const WebCore::HTMLTextAreaElement* input_element = static_cast<const WebCore::HTMLTextAreaElement*>(&element);
+ if (input_element->renderer())
+ value = S(input_element->value());
+ } else if (element.type() == WTF::AtomicString("select-one")) {
+ // TODO: This is ugly. SelectElement::value() is a non-const
+ // method. Look into fixing this on the WebKit side.
+ HTMLFormControlElement& e = const_cast<HTMLFormControlElement&>(element);
+ HTMLSelectElement& select_element = static_cast<HTMLSelectElement&>(e);
+ value = S(select_element.value());
+ }
+ field->set_value(value);
+}
+
+// static
+string16 FormManager::LabelForElement(const HTMLFormControlElement& element) {
+ RefPtr<NodeList> labels = element.document()->getElementsByTagName("label");
+ for (unsigned i = 0; i < labels->length(); ++i) {
+ Node* e = labels->item(i);
+ if (e->hasTagName(labelTag)) {
+ HTMLLabelElement* label = static_cast<HTMLLabelElement*>(e);
+ if (label->control() == &element)
+ return FindChildText(label);
+ }
+ }
+
+ // Infer the label from context if not found in label element.
+ return FormManager::InferLabelForElement(element);
+}
+
+// static
+bool FormManager::HTMLFormElementToFormData(HTMLFormElement& element,
+ RequirementsMask requirements,
+ bool get_values,
+ FormData* form) {
+ ASSERT(form);
+
+ const WebCore::Document* document = element.document();
+ if (!document)
+ return false;
+
+ if (requirements & REQUIRE_AUTOCOMPLETE && !element.autoComplete())
+ return false;
+
+ form->name = S(element.name());
+ form->method = S(element.method());
+ form->origin = GURL(S(document->documentURI()));
+ form->action = GURL(S(document->completeURL(element.action())));
+ // If the completed URL is not valid, just use the action we get from
+ // WebKit.
+ if (!form->action.is_valid())
+ form->action = GURL(S(element.action()));
+
+ // A map from a FormField's name to the FormField itself.
+ std::map<string16, FormField*> name_map;
+
+ // The extracted FormFields. We use pointers so we can store them in
+ // |name_map|.
+ ScopedVector<FormField> form_fields;
+
+ WTF::Vector<WebCore::HTMLFormControlElement*> control_elements = element.associatedElements();
+
+ // A vector of bools that indicate whether each field in the form meets the
+ // requirements and thus will be in the resulting |form|.
+ std::vector<bool> fields_extracted(control_elements.size(), false);
+ for (size_t i = 0; i < control_elements.size(); ++i) {
+ const HTMLFormControlElement* control_element = control_elements[i];
+
+ if (requirements & REQUIRE_AUTOCOMPLETE &&
+ control_element->type() == WTF::String("text")) {
+ const WebCore::HTMLInputElement* input_element = static_cast<const WebCore::HTMLInputElement*>(control_element);
+ if (!input_element->autoComplete())
+ continue;
+ }
+
+ if (requirements & REQUIRE_ELEMENTS_ENABLED && !control_element->isEnabledFormControl())
+ continue;
+
+ // Create a new FormField, fill it out and map it to the field's name.
+ FormField* field = new FormField;
+ HTMLFormControlElementToFormField(*control_element, get_values, field);
+ form_fields.push_back(field);
+ // TODO: A label element is mapped to a form control element's id.
+ // field->name() will contain the id only if the name does not exist. Add
+ // an id() method to HTMLFormControlElement and use that here.
+ name_map[field->name()] = field;
+ fields_extracted[i] = true;
+ }
+
+ // Don't extract field labels if we have no fields.
+ if (form_fields.empty())
+ return false;
+
+ // Loop through the label elements inside the form element. For each label
+ // element, get the corresponding form control element, use the form control
+ // element's name as a key into the <name, FormField> map to find the
+ // previously created FormField and set the FormField's label to the
+ // label.firstChild().nodeValue() of the label element.
+ RefPtr<WebCore::NodeList> labels = element.getElementsByTagName("label");
+ for (unsigned i = 0; i < labels->length(); ++i) {
+ WebCore::HTMLLabelElement* label = static_cast<WebCore::HTMLLabelElement*>(labels->item(i));
+ HTMLFormControlElement* field_element = label->control();
+ if (!field_element || field_element->type() == "hidden")
+ continue;
+
+ std::map<string16, FormField*>::iterator iter =
+ name_map.find(S(field_element->name()));
+ if (iter != name_map.end())
+ iter->second->set_label(FindChildText(label));
+ }
+
+ // Loop through the form control elements, extracting the label text from the
+ // DOM. We use the |fields_extracted| vector to make sure we assign the
+ // extracted label to the correct field, as it's possible |form_fields| will
+ // not contain all of the elements in |control_elements|.
+ for (size_t i = 0, field_idx = 0;
+ i < control_elements.size() && field_idx < form_fields.size(); ++i) {
+ // This field didn't meet the requirements, so don't try to find a label for
+ // it.
+ if (!fields_extracted[i])
+ continue;
+
+ const HTMLFormControlElement* control_element = control_elements[i];
+ if (form_fields[field_idx]->label().empty())
+ form_fields[field_idx]->set_label(
+ FormManager::InferLabelForElement(*control_element));
+
+ ++field_idx;
+
+ }
+ // Copy the created FormFields into the resulting FormData object.
+ for (ScopedVector<FormField>::const_iterator iter = form_fields.begin();
+ iter != form_fields.end(); ++iter) {
+ form->fields.push_back(**iter);
+ }
+
+ return true;
+}
+
+void FormManager::ExtractForms(WebCore::Document* document) {
+
+ WTF::PassRefPtr<WebCore::HTMLCollection> collection = document->forms();
+
+ WebCore::HTMLFormElement* form;
+ WebCore::HTMLInputElement* input;
+ for (Node* node = collection->firstItem();
+ node && !node->namespaceURI().isNull() && !node->namespaceURI().isEmpty();
+ node = collection->nextItem()) {
+ FormElement* form_elements = new FormElement;
+ form = static_cast<WebCore::HTMLFormElement*>(node);
+ if (form->autoComplete()) {
+ WTF::Vector<WebCore::HTMLFormControlElement*> elements = form->associatedElements();
+ size_t size = elements.size();
+ for (size_t i = 0; i < size; i++) {
+ WebCore::HTMLFormControlElement* e = elements[i];
+ form_elements->control_elements.push_back(e);
+ }
+ form_elements->form_element = form;
+ }
+ form_elements_map_[document].push_back(form_elements);
+ }
+}
+
+void FormManager::GetForms(RequirementsMask requirements,
+ std::vector<FormData>* forms) {
+ ASSERT(forms);
+
+ for (DocumentFormElementMap::iterator iter = form_elements_map_.begin();
+ iter != form_elements_map_.end(); ++iter) {
+ for (std::vector<FormElement*>::iterator form_iter = iter->second.begin();
+ form_iter != iter->second.end(); ++form_iter) {
+ FormData form;
+ if (HTMLFormElementToFormData(*(*form_iter)->form_element,
+ requirements,
+ true,
+ &form))
+ forms->push_back(form);
+ }
+ }
+}
+
+void FormManager::GetFormsInDocument(const WebCore::Document* document,
+ RequirementsMask requirements,
+ std::vector<FormData>* forms) {
+ ASSERT(document);
+ ASSERT(forms);
+
+ DocumentFormElementMap::iterator iter = form_elements_map_.find(document);
+ if (iter == form_elements_map_.end())
+ return;
+
+ // TODO: Factor this out and use it here and in GetForms.
+ const std::vector<FormElement*>& form_elements = iter->second;
+ for (std::vector<FormElement*>::const_iterator form_iter =
+ form_elements.begin();
+ form_iter != form_elements.end(); ++form_iter) {
+ FormElement* form_element = *form_iter;
+
+ // We need at least |kRequiredAutoFillFields| fields before appending this
+ // form to |forms|.
+ if (form_element->control_elements.size() < kRequiredAutoFillFields)
+ continue;
+
+ if (requirements & REQUIRE_AUTOCOMPLETE &&
+ !form_element->form_element->autoComplete())
+ continue;
+
+ FormData form;
+ FormElementToFormData(document, form_element, requirements, &form);
+ if (form.fields.size() >= kRequiredAutoFillFields)
+ forms->push_back(form);
+ }
+}
+
+bool FormManager::FindForm(const HTMLFormElement& element,
+ RequirementsMask requirements,
+ FormData* form) {
+ ASSERT(form);
+
+ const WebCore::Document* document = element.document();
+ DocumentFormElementMap::const_iterator document_iter =
+ form_elements_map_.find(document);
+ if (document_iter == form_elements_map_.end())
+ return false;
+
+ for (std::vector<FormElement*>::const_iterator iter =
+ document_iter->second.begin();
+ iter != document_iter->second.end(); ++iter) {
+ if ((*iter)->form_element->name() != element.name())
+ continue;
+ return FormElementToFormData(document, *iter, requirements, form);
+ }
+ return false;
+}
+
+bool FormManager::FindFormWithFormControlElement(
+ const HTMLFormControlElement& element,
+ RequirementsMask requirements,
+ FormData* form) {
+ ASSERT(form);
+
+ const WebCore::Document* document = element.document();
+ if (form_elements_map_.find(document) == form_elements_map_.end())
+ return false;
+
+ const std::vector<FormElement*> forms = form_elements_map_[document];
+ for (std::vector<FormElement*>::const_iterator iter = forms.begin();
+ iter != forms.end(); ++iter) {
+ const FormElement* form_element = *iter;
+
+ for (std::vector<HTMLFormControlElement*>::const_iterator iter =
+ form_element->control_elements.begin();
+ iter != form_element->control_elements.end(); ++iter) {
+ if ((*iter)->name() == element.name()) {
+ HTMLFormElementToFormData(
+ *form_element->form_element, requirements, true, form);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool FormManager::FillForm(const FormData& form) {
+ FormElement* form_element = NULL;
+
+ for (DocumentFormElementMap::iterator iter = form_elements_map_.begin();
+ iter != form_elements_map_.end(); ++iter) {
+ const WebCore::Document* document = iter->first;
+
+ for (std::vector<FormElement*>::iterator form_iter = iter->second.begin();
+ form_iter != iter->second.end(); ++form_iter) {
+ // TODO: matching on form name here which is not guaranteed to
+ // be unique for the page, nor is it guaranteed to be non-empty. Need to
+ // find a way to uniquely identify the form cross-process. For now we'll
+ // check form name and form action for identity.
+ // http://crbug.com/37990 test file sample8.html.
+ // Also note that WebString() == WebString(string16()) does not seem to
+ // evaluate to |true| for some reason TBD, so forcing to string16.
+ string16 element_name(S((*form_iter)->form_element->name()));
+ GURL action(
+ S(document->completeURL((*form_iter)->form_element->action()).string()));
+ if (element_name == form.name && action == form.action) {
+ form_element = *form_iter;
+ break;
+ }
+ }
+ }
+
+ if (!form_element)
+ return false;
+
+ // It's possible that the site has injected fields into the form after the
+ // page has loaded, so we can't assert that the size of the cached control
+ // elements is equal to the size of the fields in |form|. Fortunately, the
+ // one case in the wild where this happens, paypal.com signup form, the fields
+ // are appended to the end of the form and are not visible.
+
+ for (size_t i = 0, j = 0;
+ i < form_element->control_elements.size() && j < form.fields.size();
+ ++i, ++j) {
+ // Once again, empty WebString != empty string16, so we have to explicitly
+ // check for this case.
+ if (form_element->control_elements[i]->name().length() == 0 &&
+ form.fields[j].name().empty())
+ continue;
+
+ // We assume that the intersection of the fields in
+ // |form_element->control_elements| and |form.fields| is ordered, but it's
+ // possible that one or the other sets may have more fields than the other,
+ // so loop past non-matching fields in the set with more elements.
+ while (S(form_element->control_elements[i]->name()) !=
+ form.fields[j].name()) {
+ if (form_element->control_elements.size() > form.fields.size()) {
+ // We're at the end of the elements already.
+ if (i + 1 == form_element->control_elements.size())
+ break;
+ ++i;
+ } else if (form.fields.size() > form_element->control_elements.size()) {
+ // We're at the end of the elements already.
+ if (j + 1 == form.fields.size())
+ break;
+ ++j;
+ } else {
+ // Shouldn't get here.
+ ASSERT(false);
+ }
+
+ continue;
+ }
+
+ HTMLFormControlElement* element = form_element->control_elements[i];
+ if (!form.fields[j].value().empty() &&
+ element->type() != WTF::String("submit")) {
+ if (element->type() == WTF::String("text")) {
+ WebCore::HTMLInputElement* input_element = static_cast<WebCore::HTMLInputElement*>(element);
+ // If the maxlength attribute contains a negative value, maxLength()
+ // returns the default maxlength value.
+ input_element->setValue(
+ WTF::String(form.fields[j].value().substr(0, input_element->maxLength()).c_str()));
+ input_element->setAutofilled(true);
+ } else if (element->type() ==
+ WTF::String("select-one")) {
+ WebCore::HTMLSelectElement* select_element = static_cast<WebCore::HTMLSelectElement*>(element);
+ select_element->setValue(WTF::String(form.fields[j].value().c_str()));
+ }
+ }
+ }
+
+ return true;
+}
+
+void FormManager::FillForms(const std::vector<webkit_glue::FormData>& forms) {
+ for (std::vector<webkit_glue::FormData>::const_iterator iter = forms.begin();
+ iter != forms.end(); ++iter) {
+ FillForm(*iter);
+ }
+}
+
+void FormManager::Reset() {
+ for (DocumentFormElementMap::iterator iter = form_elements_map_.begin();
+ iter != form_elements_map_.end(); ++iter) {
+ STLDeleteElements(&iter->second);
+ }
+ form_elements_map_.clear();
+}
+
+void FormManager::ResetFrame(const WebCore::Document* document) {
+
+ DocumentFormElementMap::iterator iter = form_elements_map_.find(document);
+ if (iter != form_elements_map_.end()) {
+ STLDeleteElements(&iter->second);
+ form_elements_map_.erase(iter);
+ }
+}
+
+// static
+bool FormManager::FormElementToFormData(const WebCore::Document* document,
+ const FormElement* form_element,
+ RequirementsMask requirements,
+ FormData* form) {
+ if (requirements & REQUIRE_AUTOCOMPLETE &&
+ !form_element->form_element->autoComplete())
+ return false;
+
+ form->name = S(form_element->form_element->name());
+ form->method = S(form_element->form_element->method());
+ form->origin = GURL(S(document->documentURI()));
+ form->action = GURL(S(document->completeURL(form_element->form_element->action())));
+
+ // If the completed URL is not valid, just use the action we get from
+ // WebKit.
+ if (!form->action.is_valid())
+ form->action = GURL(S(form_element->form_element->action()));
+
+ // Form elements loop.
+ for (std::vector<HTMLFormControlElement*>::const_iterator element_iter =
+ form_element->control_elements.begin();
+ element_iter != form_element->control_elements.end(); ++element_iter) {
+ const HTMLFormControlElement* control_element = *element_iter;
+
+ if (requirements & REQUIRE_AUTOCOMPLETE &&
+ control_element->type() == WTF::String("text")) {
+ const WebCore::HTMLInputElement* input_element =
+ static_cast<const WebCore::HTMLInputElement*>(control_element);
+ if (!input_element->autoComplete())
+ continue;
+ }
+
+ if (requirements & REQUIRE_ELEMENTS_ENABLED && !control_element->isEnabledFormControl())
+ continue;
+
+ FormField field;
+ HTMLFormControlElementToFormField(*control_element, false, &field);
+ form->fields.push_back(field);
+ }
+
+ return true;
+}
+
+// static
+string16 FormManager::InferLabelForElement(
+ const HTMLFormControlElement& element) {
+ string16 inferred_label;
+ Node* previous = element.previousSibling();
+ if (previous) {
+ if (previous->isTextNode()) {
+ inferred_label = S(previous->nodeValue());
+ TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label);
+ }
+
+ // If we didn't find text, check for previous paragraph.
+ // Eg. <p>Some Text</p><input ...>
+ // Note the lack of whitespace between <p> and <input> elements.
+ if (inferred_label.empty()) {
+ if (previous->isElementNode()) {
+ if (previous->hasTagName(pTag)) {
+ inferred_label = FindChildText((HTMLElement*)previous);
+ }
+ }
+ }
+
+ // If we didn't find paragraph, check for previous paragraph to this.
+ // Eg. <p>Some Text</p> <input ...>
+ // Note the whitespace between <p> and <input> elements.
+ if (inferred_label.empty()) {
+ previous = previous->previousSibling();
+ if (previous) {
+ if (previous->hasTagName(pTag)) {
+ inferred_label = FindChildText((HTMLElement*)previous);
+ }
+ }
+ }
+ }
+
+ // If we didn't find paragraph, check for table cell case.
+ // Eg. <tr><td>Some Text</td><td><input ...></td></tr>
+ // Eg. <tr><td><b>Some Text</b></td><td><b><input ...></b></td></tr>
+ if (inferred_label.empty()) {
+ Node* parent = element.parentNode();
+ while (parent &&
+ !parent->hasTagName(tdTag))
+ parent = parent->parentNode();
+
+ if (parent) {
+ if (parent->hasTagName(tdTag)) {
+ previous = parent->previousSibling();
+
+ // Skip by any intervening text nodes.
+ while (previous && previous->isTextNode())
+ previous = previous->previousSibling();
+
+ if (previous) {
+ if (previous->hasTagName(tdTag)) {
+ inferred_label = FindChildText((HTMLElement*)previous);
+ }
+ }
+ }
+ }
+ }
+ return inferred_label;
+}
+
+}
diff --git a/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.h b/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.h
new file mode 100644
index 0000000..395e651
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved.
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FormManagerAndroid_h
+#define FormManagerAndroid_h
+
+#include "ChromiumIncludes.h"
+
+#include <map>
+#include <vector>
+
+// TODO: This file is taken from chromium/chrome/renderer/form_manager.h and
+// customised to use WebCore types rather than WebKit API types. It would be
+// nice and would ease future merge pain if the two could be combined.
+
+namespace webkit_glue {
+struct FormData;
+class FormField;
+} // namespace webkit_glue
+
+namespace WebCore {
+ class HTMLFormControlElement;
+ class HTMLFormElement;
+ class Document;
+}
+
+namespace android {
+
+// Manages the forms in a Document.
+class FormManager {
+ public:
+ // A bit field mask for form requirements.
+ enum RequirementsMask {
+ REQUIRE_NONE = 0x0, // No requirements.
+ REQUIRE_AUTOCOMPLETE = 0x1, // Require that autocomplete != off.
+ REQUIRE_ELEMENTS_ENABLED = 0x2 // Require that disabled attribute is off.
+ };
+
+ FormManager();
+ virtual ~FormManager();
+
+ // Fills out a FormField object from a given WebFormControlElement.
+ // If |get_value| is true, |field| will have the value set from |element|.
+ static void HTMLFormControlElementToFormField(
+ const WebCore::HTMLFormControlElement& element,
+ bool get_value,
+ webkit_glue::FormField* field);
+
+ // Returns the corresponding label for |element|. WARNING: This method can
+ // potentially be very slow. Do not use during any code paths where the page
+ // is loading.
+ static string16 LabelForElement(const WebCore::HTMLFormControlElement& element);
+
+ // Fills out a FormData object from a given WebFormElement. If |get_values|
+ // is true, the fields in |form| will have the values filled out. Returns
+ // true if |form| is filled out; it's possible that |element| won't meet the
+ // requirements in |requirements|. This also returns false if there are no
+ // fields in |form|.
+ // TODO: Remove the user of this in RenderView and move this to
+ // private.
+ static bool HTMLFormElementToFormData(WebCore::HTMLFormElement& element,
+ RequirementsMask requirements,
+ bool get_values,
+ webkit_glue::FormData* form);
+
+ // Scans the DOM in |document| extracting and storing forms.
+ void ExtractForms(WebCore::Document* document);
+
+ // Returns a vector of forms that match |requirements|.
+ void GetForms(RequirementsMask requirements,
+ std::vector<webkit_glue::FormData>* forms);
+
+ // Returns a vector of forms in |document| that match |requirements|.
+ void GetFormsInDocument(const WebCore::Document* document,
+ RequirementsMask requirements,
+ std::vector<webkit_glue::FormData>* forms);
+
+ // Returns the cached FormData for |element|. Returns true if the form was
+ // found in the cache.
+ bool FindForm(const WebCore::HTMLFormElement& element,
+ RequirementsMask requirements,
+ webkit_glue::FormData* form);
+
+ // Finds the form that contains |element| and returns it in |form|. Returns
+ // false if the form is not found.
+ bool FindFormWithFormControlElement(
+ const WebCore::HTMLFormControlElement& element,
+ RequirementsMask requirements,
+ webkit_glue::FormData* form);
+
+ // Fills the form represented by |form|. |form| should have the name set to
+ // the name of the form to fill out, and the number of elements and values
+ // must match the number of stored elements in the form.
+ // TODO: Is matching on name alone good enough? It's possible to
+ // store multiple forms with the same names from different frames.
+ bool FillForm(const webkit_glue::FormData& form);
+
+ // Fills all of the forms in the cache with form data from |forms|.
+ void FillForms(const std::vector<webkit_glue::FormData>& forms);
+
+ // Resets the stored set of forms.
+ void Reset();
+
+ // Resets the forms for the specified |document|.
+ void ResetFrame(const WebCore::Document* document);
+
+ private:
+ // Stores the HTMLFormElement and the form control elements for a form.
+ struct FormElement {
+ WebCore::HTMLFormElement* form_element;
+ std::vector<WebCore::HTMLFormControlElement*> control_elements;
+ };
+
+ // A map of vectors of FormElements keyed by the Document containing each
+ // form.
+ typedef std::map<const WebCore::Document*, std::vector<FormElement*> >
+ DocumentFormElementMap;
+
+ // Converts a FormElement to FormData storage. Returns false if the form does
+ // not meet all the requirements in the requirements mask.
+ static bool FormElementToFormData(const WebCore::Document* document,
+ const FormElement* form_element,
+ RequirementsMask requirements,
+ webkit_glue::FormData* form);
+
+ // Infers corresponding label for |element| from surrounding context in the
+ // DOM. Contents of preceeding <p> tag or preceeding text element found in
+ // the form.
+ static string16 InferLabelForElement(
+ const WebCore::HTMLFormControlElement& element);
+
+ // The map of form elements.
+ DocumentFormElementMap form_elements_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(FormManager);
+};
+
+} // namespace android
+
+#endif // FormManagerAndroid_h
diff --git a/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.cpp b/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.cpp
new file mode 100644
index 0000000..598b9c4
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "MainThreadProxy.h"
+
+#include <wtf/MainThread.h>
+
+void MainThreadProxy::CallOnMainThread(CallOnMainThreadFunction f, void* c)
+{
+ callOnMainThread(f, c);
+}
diff --git a/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.h b/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.h
new file mode 100644
index 0000000..d9310bb
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/autofill/MainThreadProxy.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MAIN_THREAD_PROXY_H
+#define MAIN_THREAD_PROXY_H
+
+typedef void CallOnMainThreadFunction(void*);
+
+class MainThreadProxy
+{
+public:
+ static void CallOnMainThread(CallOnMainThreadFunction, void*);
+};
+
+#endif
diff --git a/WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp b/WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp
new file mode 100644
index 0000000..08d5e58
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/autofill/WebAutoFill.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebAutoFill.h"
+
+#if ENABLE(WEB_AUTOFILL)
+
+#include "AutoFillHostAndroid.h"
+#include "Document.h"
+#include "Frame.h"
+#include "FormData.h"
+#include "FormManagerAndroid.h"
+#include "FrameLoader.h"
+#include "HTMLFormControlElement.h"
+#include "MainThreadProxy.h"
+#include "Node.h"
+#include "WebFrame.h"
+#include "WebRequestContext.h"
+#include "WebUrlLoaderClient.h"
+#include "WebViewCore.h"
+
+namespace android
+{
+
+WebAutoFill::WebAutoFill()
+{
+ mFormManager = new FormManager();
+ mQueryId = 1;
+
+ AndroidURLRequestContextGetter::Get()->SetURLRequestContext(WebRequestContext::GetAndroidContext());
+ AndroidURLRequestContextGetter::Get()->SetIOThread(WebUrlLoaderClient::ioThread());
+ TabContents* tabContents = new TabContents();
+ mAutoFillManager = new AutoFillManager(tabContents);
+
+ // FIXME: For testing use a precanned profile. This should come from Java land!
+ mAutoFillProfile = new AutoFillProfile();
+ mAutoFillProfile->SetInfo(AutoFillType(NAME_FULL), string16(ASCIIToUTF16("John Smith")));
+ mAutoFillProfile->SetInfo(AutoFillType(EMAIL_ADDRESS), string16(ASCIIToUTF16("jsmith@gmail.com")));
+ mAutoFillProfile->SetInfo(AutoFillType(ADDRESS_HOME_ZIP), string16(ASCIIToUTF16("AB12 3DE")));
+ mAutoFillProfile->SetInfo(AutoFillType(PHONE_HOME_WHOLE_NUMBER), string16(ASCIIToUTF16("0123456789")));
+
+ std::vector<AutoFillProfile> profiles;
+ profiles.push_back(*mAutoFillProfile);
+ tabContents->profile()->GetPersonalDataManager()->SetProfiles(&profiles);
+ mAutoFillHost = new AutoFillHostAndroid(this);
+ tabContents->SetAutoFillHost(mAutoFillHost.get());
+}
+
+WebAutoFill::~WebAutoFill()
+{
+ mQueryMap.clear();
+}
+
+void WebAutoFill::searchDocument(WebCore::Document* document)
+{
+ // TODO: This method is called when the main frame finishes loading and
+ // scans the document for forms and tries to work out the type of the
+ // fields in those forms. It's currently synchronous and might be slow
+ // if the page has many or complex forms. Might want to make this an
+ // async method.
+ if (!mFormManager)
+ return;
+
+ mQueryMap.clear();
+ mQueryId = 1;
+ mAutoFillManager->Reset();
+ mFormManager->Reset();
+ mFormManager->ExtractForms(document);
+ mForms.clear();
+ mFormManager->GetForms(FormManager::REQUIRE_AUTOCOMPLETE, &mForms);
+ mAutoFillManager->FormsSeen(mForms);
+}
+
+void WebAutoFill::formFieldFocused(WebCore::HTMLFormControlElement* formFieldElement)
+{
+ // Get the FormField from the Node.
+ webkit_glue::FormField formField;
+ FormManager::HTMLFormControlElementToFormField(*formFieldElement, false, &formField);
+ formField.set_label(FormManager::LabelForElement(*formFieldElement));
+
+ webkit_glue::FormData* form = new webkit_glue::FormData;
+ mFormManager->FindFormWithFormControlElement(*formFieldElement, FormManager::REQUIRE_AUTOCOMPLETE, form);
+ mQueryMap[mQueryId] = form;
+
+ mAutoFillManager->GetAutoFillSuggestions(mQueryId, false, formField);
+ mQueryId++;
+}
+
+void WebAutoFill::fillFormFields(int queryId, const string16& value, const string16& label, int uniqueId)
+{
+ webkit_glue::FormData* form = mQueryMap[queryId];
+ mAutoFillManager->FillAutoFillFormData(queryId, *form, value, label, uniqueId);
+}
+
+void WebAutoFill::fillFormInPage(int queryId, const webkit_glue::FormData& form)
+{
+ mFormManager->FillForm(form);
+}
+
+}
+
+#endif
diff --git a/WebKit/android/WebCoreSupport/autofill/WebAutoFill.h b/WebKit/android/WebCoreSupport/autofill/WebAutoFill.h
new file mode 100644
index 0000000..335f9b2
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/autofill/WebAutoFill.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebAutoFill_h
+#define WebAutoFill_h
+
+#if ENABLE(WEB_AUTOFILL)
+
+#include "ChromiumIncludes.h"
+
+#include <map>
+#include <vector>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+
+class AutoFillManager;
+class AutoFillProfile;
+class AutoFillHost;
+
+namespace WebCore {
+class Document;
+class HTMLFormControlElement;
+}
+
+namespace android
+{
+class FormManager;
+class WebViewCore;
+
+class WebAutoFill : public Noncopyable
+{
+public:
+ WebAutoFill();
+ virtual ~WebAutoFill();
+
+ void searchDocument(WebCore::Document*);
+ void formFieldFocused(WebCore::HTMLFormControlElement*);
+ void fillFormFields(int queryId, const string16& value, const string16& label, int uniqueId);
+ void fillFormInPage(int queryId, const webkit_glue::FormData& form);
+
+private:
+ OwnPtr<FormManager> mFormManager;
+ OwnPtr<AutoFillManager> mAutoFillManager;
+ OwnPtr<AutoFillProfile> mAutoFillProfile;
+ OwnPtr<AutoFillHost> mAutoFillHost;
+
+ typedef std::vector<webkit_glue::FormData, std::allocator<webkit_glue::FormData> > FormList;
+ FormList mForms;
+
+ typedef std::map<int, webkit_glue::FormData*> AutoFillQueryMap;
+ AutoFillQueryMap mQueryMap;
+ int mQueryId;
+};
+
+}
+
+#endif // ENABLE(WEB_AUTOFILL)
+#endif // WebAutoFill_h
diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp
index a717301..c1cb907 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -120,6 +120,10 @@
#include "WebArchiveAndroid.h"
#endif
+#if ENABLE(WEB_AUTOFILL)
+#include "autofill/WebAutoFill.h"
+#endif
+
using namespace JSC::Bindings;
static String* gUploadFileLabel;
@@ -639,6 +643,13 @@ WebFrame::didFinishLoad(WebCore::Frame* frame)
(int)loadType, isMainFrame);
checkException(env);
env->DeleteLocalRef(urlStr);
+#if ENABLE(WEB_AUTOFILL)
+ // TODO: Need to consider child frames.
+ if (isMainFrame) {
+ EditorClientAndroid* editorClient = static_cast<EditorClientAndroid*>(mPage->editorClient());
+ editorClient->getAutoFill()->searchDocument(frame->document());
+ }
+#endif
}
void