summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorGeorge Mount <mount@google.com>2012-03-12 07:10:39 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-03-12 07:10:39 -0700
commit668a73488d6938004d25b6c155573e97b6600182 (patch)
tree4c157fb050a3a5470b2ec786ce37d4be104f0ed0 /Source
parentb3f4d3af0b06dc168453641e249d0cb9eec9b570 (diff)
parent730ac8198c5c9a59a2b11e54657155f3ea33d83f (diff)
downloadexternal_webkit-668a73488d6938004d25b6c155573e97b6600182.zip
external_webkit-668a73488d6938004d25b6c155573e97b6600182.tar.gz
external_webkit-668a73488d6938004d25b6c155573e97b6600182.tar.bz2
Merge "Add back auto-completion and auto-fill."
Diffstat (limited to 'Source')
-rw-r--r--Source/WebKit/android/jni/WebCoreJni.cpp10
-rw-r--r--Source/WebKit/android/jni/WebCoreJni.h1
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp129
-rw-r--r--Source/WebKit/android/jni/WebViewCore.h11
-rw-r--r--Source/WebKit/android/nav/WebView.cpp21
5 files changed, 129 insertions, 43 deletions
diff --git a/Source/WebKit/android/jni/WebCoreJni.cpp b/Source/WebKit/android/jni/WebCoreJni.cpp
index 5a142c8..6dfc9f1 100644
--- a/Source/WebKit/android/jni/WebCoreJni.cpp
+++ b/Source/WebKit/android/jni/WebCoreJni.cpp
@@ -112,6 +112,16 @@ jstring stdStringToJstring(JNIEnv* env, const std::string& str, bool validOnZero
return !str.empty() || validOnZeroLength ? env->NewStringUTF(str.c_str()) : 0;
}
+jobject intRectToRect(JNIEnv* env, const WebCore::IntRect& rect)
+{
+ jclass rectClass = env->FindClass("android/graphics/Rect");
+ ALOG_ASSERT(rectClass, "Could not find android/graphics/Rect");
+ jmethodID rectInit = env->GetMethodID(rectClass, "<init>", "(IIII)V");
+ ALOG_ASSERT(rectInit, "Could not find init method on Rect");
+ return env->NewObject(rectClass, rectInit, rect.x(), rect.y(),
+ rect.maxX(), rect.maxY());
+}
+
jobjectArray intRectVectorToRectArray(JNIEnv* env, Vector<WebCore::IntRect>& rects)
{
jclass rectClass = env->FindClass("android/graphics/Rect");
diff --git a/Source/WebKit/android/jni/WebCoreJni.h b/Source/WebKit/android/jni/WebCoreJni.h
index 25aa986..e8cc6ea 100644
--- a/Source/WebKit/android/jni/WebCoreJni.h
+++ b/Source/WebKit/android/jni/WebCoreJni.h
@@ -92,6 +92,7 @@ jstring stdStringToJstring(JNIEnv*, const std::string&, bool validOnZeroLength =
jobjectArray intRectVectorToRectArray(JNIEnv*, Vector<WebCore::IntRect>&);
+jobject intRectToRect(JNIEnv* env, const WebCore::IntRect& rect);
}
#endif
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp
index 0589468..1bba9b8 100644
--- a/Source/WebKit/android/jni/WebViewCore.cpp
+++ b/Source/WebKit/android/jni/WebViewCore.cpp
@@ -123,6 +123,7 @@
#include "TypingCommand.h"
#include "WebCache.h"
#include "WebCoreFrameBridge.h"
+#include "WebCoreJni.h"
#include "WebFrameView.h"
#include "WindowsKeyboardCodes.h"
#include "android_graphics.h"
@@ -463,7 +464,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_getDeviceOrientationService = GetJMethod(env, clazz, "getDeviceOrientationService", "()Landroid/webkit/DeviceOrientationService;");
m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;I)V");
m_javaGlue->m_formDidBlur = GetJMethod(env, clazz, "formDidBlur", "(I)V");
- m_javaGlue->m_focusNodeChanged = GetJMethod(env, clazz, "focusNodeChanged", "(Landroid/webkit/WebViewCore$WebKitHitTest;)V");
+ m_javaGlue->m_focusNodeChanged = GetJMethod(env, clazz, "focusNodeChanged", "(ILandroid/webkit/WebViewCore$WebKitHitTest;)V");
m_javaGlue->m_getPluginClass = GetJMethod(env, clazz, "getPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;");
m_javaGlue->m_showFullScreenPlugin = GetJMethod(env, clazz, "showFullScreenPlugin", "(Landroid/webkit/ViewManager$ChildView;II)V");
m_javaGlue->m_hideFullScreenPlugin = GetJMethod(env, clazz, "hideFullScreenPlugin", "()V");
@@ -483,7 +484,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
#endif
m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V");
m_javaGlue->m_selectAt = GetJMethod(env, clazz, "selectAt", "(II)V");
- m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(ILjava/lang/String;IZZLjava/lang/String;IIII)V");
+ m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(ILjava/lang/String;IZZZLjava/lang/String;Ljava/lang/String;IIIILandroid/graphics/Rect;I)V");
m_javaGlue->m_updateMatchCount = GetJMethod(env, clazz, "updateMatchCount", "(IILjava/lang/String;)V");
m_javaGlue->m_chromeCanTakeFocus = GetJMethod(env, clazz, "chromeCanTakeFocus", "(I)Z");
m_javaGlue->m_chromeTakeFocus = GetJMethod(env, clazz, "chromeTakeFocus", "(I)V");
@@ -3217,41 +3218,8 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
bool handled = framePtr->eventHandler()->handleMouseReleaseEvent(mouseUp);
webFrame->setUserInitiatedAction(false);
- // If the user clicked on a textfield, make the focusController active
- // so we show the blinking cursor.
WebCore::Node* focusNode = currentFocus();
- if (focusNode) {
- WebCore::RenderTextControl* rtc = toRenderTextControl(focusNode);
- if (rtc) {
- bool ime = !shouldSuppressKeyboard(focusNode)
- && !(static_cast<WebCore::HTMLInputElement*>(focusNode))->readOnly();
- if (ime) {
-#if ENABLE(WEB_AUTOFILL)
- if (rtc->isTextField()) {
- EditorClientAndroid* editorC = static_cast<EditorClientAndroid*>(framePtr->page()->editorClient());
- WebAutofill* autoFill = editorC->getAutofill();
- autoFill->formFieldFocused(static_cast<HTMLFormControlElement*>(focusNode));
- }
-#endif
- if (!fake)
- initEditField(focusNode);
- } else if (!fake) {
- requestKeyboard(false);
- }
- } else if (!fake){
- // If the selection is contentEditable, show the keyboard so the
- // user can type. Otherwise hide the keyboard because no text
- // input is needed.
- if (isContentEditable(focusNode)) {
- initEditField(focusNode);
- } else if (!nodeIsPlugin(focusNode)) {
- clearTextEntry();
- }
- }
- } else if (!fake) {
- // There is no focusNode, so the keyboard is not needed.
- clearTextEntry();
- }
+ initializeTextInput(focusNode, fake);
return handled;
}
@@ -3295,6 +3263,16 @@ int WebViewCore::getMaxLength(Node* node)
return maxLength;
}
+String WebViewCore::getFieldName(Node* node)
+{
+ String name;
+ if (node->hasTagName(WebCore::HTMLNames::inputTag)) {
+ HTMLInputElement* htmlInput = static_cast<HTMLInputElement*>(node);
+ name = htmlInput->name();
+ }
+ return name;
+}
+
bool WebViewCore::isSpellCheckEnabled(Node* node)
{
bool isEnabled = true;
@@ -3305,6 +3283,34 @@ bool WebViewCore::isSpellCheckEnabled(Node* node)
return isEnabled;
}
+bool WebViewCore::isAutoCompleteEnabled(Node* node)
+{
+ bool isEnabled = false;
+ if (node->hasTagName(WebCore::HTMLNames::inputTag)) {
+ HTMLInputElement* htmlInput = static_cast<HTMLInputElement*>(node);
+ isEnabled = htmlInput->autoComplete();
+ }
+ return isEnabled;
+}
+
+WebCore::IntRect WebViewCore::boundingRect(WebCore::Node* node,
+ LayerAndroid* layer)
+{
+ // Caret selection
+ IntRect boundingRect;
+ if (node) {
+ RenderObject* render = node->renderer();
+ if (render && !render->isBody()) {
+ IntPoint offset = convertGlobalContentToFrameContent(IntPoint(),
+ node->document()->frame());
+ WebViewCore::layerToAbsoluteOffset(layer, offset);
+ boundingRect = render->absoluteBoundingBoxRect(true);
+ boundingRect.move(-offset.x(), -offset.y());
+ }
+ }
+ return boundingRect;
+}
+
void WebViewCore::initEditField(Node* node)
{
String text = getInputText(node);
@@ -3326,13 +3332,19 @@ void WebViewCore::initEditField(Node* node)
bool spellCheckEnabled = isSpellCheckEnabled(node);
int maxLength = getMaxLength(node);
String label = requestLabel(document->frame(), node);
+ bool autoComplete = isAutoCompleteEnabled(node);
+ jstring name = wtfStringToJstring(env, getFieldName(node), false);
jstring fieldText = wtfStringToJstring(env, text, true);
jstring labelText = wtfStringToJstring(env, text, false);
+ LayerAndroid* layer = 0;
+ int layerId = platformLayerIdFromNode(node, &layer);
+ jobject nodeBounds = intRectToRect(env, boundingRect(node, layer));
SelectText* selectText = createSelectText(focusedFrame()->selection()->selection());
env->CallVoidMethod(javaObject.get(), m_javaGlue->m_initEditField,
reinterpret_cast<int>(node), fieldText, inputType,
- spellCheckEnabled, isNextText, labelText, start, end,
- reinterpret_cast<int>(selectText), maxLength);
+ spellCheckEnabled, autoComplete, isNextText, name, labelText,
+ start, end, reinterpret_cast<int>(selectText), maxLength,
+ nodeBounds, layerId);
checkException(env);
}
@@ -3382,13 +3394,49 @@ WebCore::Node* nextNodeWithinParent(WebCore::Node* parent, WebCore::Node* start)
return 0;
}
+void WebViewCore::initializeTextInput(WebCore::Node* node, bool fake)
+{
+ if (node) {
+ if (isTextInput(node)) {
+ initEditField(node);
+ WebCore::RenderTextControl* rtc = toRenderTextControl(node);
+ if (rtc && node->hasTagName(HTMLNames::inputTag)) {
+ HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node);
+ bool ime = !shouldSuppressKeyboard(node) && !inputElement->readOnly();
+ if (ime) {
+#if ENABLE(WEB_AUTOFILL)
+ if (rtc->isTextField()) {
+ Page* page = node->document()->page();
+ EditorClient* editorClient = page->editorClient();
+ EditorClientAndroid* androidEditor =
+ static_cast<EditorClientAndroid*>(editorClient);
+ WebAutofill* autoFill = androidEditor->getAutofill();
+ autoFill->formFieldFocused(inputElement);
+ }
+#endif
+ } else if (!fake) {
+ requestKeyboard(false);
+ }
+ }
+ } else if (!fake && !nodeIsPlugin(node)) {
+ // not a text entry field, put away the keyboard.
+ clearTextEntry();
+ }
+ } else if (!fake) {
+ // There is no focusNode, so the keyboard is not needed.
+ clearTextEntry();
+ }
+}
+
void WebViewCore::focusNodeChanged(WebCore::Node* newFocus)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject javaObject = m_javaGlue->object(env);
if (!javaObject.get())
return;
- if (!isTextInput(newFocus) && m_blurringNodePointer) {
+ if (isTextInput(newFocus))
+ initializeTextInput(newFocus);
+ else if (m_blurringNodePointer) {
env->CallVoidMethod(javaObject.get(), m_javaGlue->m_formDidBlur, m_blurringNodePointer);
checkException(env);
m_blurringNodePointer = 0;
@@ -3420,7 +3468,8 @@ void WebViewCore::focusNodeChanged(WebCore::Node* newFocus)
}
AndroidHitTestResult androidHitTest(this, focusHitResult);
jobject jHitTestObj = androidHitTest.createJavaObject(env);
- env->CallVoidMethod(javaObject.get(), m_javaGlue->m_focusNodeChanged, jHitTestObj);
+ env->CallVoidMethod(javaObject.get(), m_javaGlue->m_focusNodeChanged,
+ reinterpret_cast<int>(newFocus), jHitTestObj);
env->DeleteLocalRef(jHitTestObj);
}
diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h
index c5704e0..ff55c00 100644
--- a/Source/WebKit/android/jni/WebViewCore.h
+++ b/Source/WebKit/android/jni/WebViewCore.h
@@ -670,6 +670,14 @@ namespace android {
void initEditField(Node* node);
/**
+ * If node is not a text input field or if it explicitly requests
+ * not to have keyboard input, then the soft keyboard is closed. If
+ * it is a text input field then initEditField is called and
+ * auto-fill information is requested for HTML form input fields.
+ */
+ void initializeTextInput(Node* node, bool fake = false);
+
+ /**
* Gets the input type a Node. NONE is returned if it isn't an
* input field.
*/
@@ -713,6 +721,9 @@ namespace android {
void selectWordAroundPosition(Frame* frame, VisiblePosition pos);
SelectText* createSelectText(const VisibleSelection&);
static int getMaxLength(Node* node);
+ static String getFieldName(Node* node);
+ static bool isAutoCompleteEnabled(Node* node);
+ IntRect boundingRect(Node* node, LayerAndroid* layer);
// called from constructor, to add this to a global list
static void addInstance(WebViewCore*);
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index 03dd866..eddf0ab 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -616,7 +616,12 @@ int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) {
if (!selectText || !m_baseLayer)
return -1;
int layerId = selectText->caretLayerId(handleId);
- IntRect rect = selectText->caretRect(handleId);
+ cursorRect = selectText->caretRect(handleId);
+ mapLayerRect(layerId, cursorRect);
+ return layerId;
+}
+
+void mapLayerRect(int layerId, SkIRect& rect) {
if (layerId != -1) {
// We need to make sure the drawTransform is up to date as this is
// called before a draw() or drawGL()
@@ -626,8 +631,6 @@ int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) {
if (layer && layer->drawTransform())
rect = layer->drawTransform()->mapRect(rect);
}
- cursorRect.set(rect.x(), rect.y(), rect.maxX(), rect.maxY());
- return layerId;
}
bool m_isDrawingPaused;
@@ -1163,6 +1166,16 @@ static jboolean nativeIsBaseFirst(JNIEnv *env, jobject obj, jint nativeView)
return select ? select->isBaseFirst() : false;
}
+static void nativeMapLayerRect(JNIEnv *env, jobject obj, jint nativeView,
+ jint layerId, jobject rect)
+{
+ WebView* webview = reinterpret_cast<WebView*>(nativeView);
+ SkIRect nativeRect;
+ GraphicsJNI::jrect_to_irect(env, rect, &nativeRect);
+ webview->mapLayerRect(layerId, nativeRect);
+ GraphicsJNI::irect_to_jrect(nativeRect, env, rect);
+}
+
/*
* JNI registration
*/
@@ -1239,6 +1252,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeGetHandleLayerId },
{ "nativeIsBaseFirst", "(I)Z",
(void*) nativeIsBaseFirst },
+ { "nativeMapLayerRect", "(IILandroid/graphics/Rect;)V",
+ (void*) nativeMapLayerRect },
};
int registerWebView(JNIEnv* env)