diff options
author | George Mount <mount@google.com> | 2012-03-12 07:10:39 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-03-12 07:10:39 -0700 |
commit | 668a73488d6938004d25b6c155573e97b6600182 (patch) | |
tree | 4c157fb050a3a5470b2ec786ce37d4be104f0ed0 /Source/WebKit/android/jni | |
parent | b3f4d3af0b06dc168453641e249d0cb9eec9b570 (diff) | |
parent | 730ac8198c5c9a59a2b11e54657155f3ea33d83f (diff) | |
download | external_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/WebKit/android/jni')
-rw-r--r-- | Source/WebKit/android/jni/WebCoreJni.cpp | 10 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebCoreJni.h | 1 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebViewCore.cpp | 129 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebViewCore.h | 11 |
4 files changed, 111 insertions, 40 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*); |